是否可以矢量化 pandas 数据帧中从源到目标数组的距离计算?
Is it possible to vectorize the calculation of the distance from a source to an array of targets in a pandas Dataframe?
我目前有一个 pandas DataFrame 设置如下:
ID, Source Coord, Target Coords
1, (35, -75), [(30, -72), (31, -71), ...]
2, (34, -74), [(50, -50), (45,-45), ...]
源坐标和目标坐标是纬度和经度。我有一个矢量化函数来计算从源到某些目标节点的距离:
from numba import njit
@njit
def haversine_nb(lat1, lon1, lat2, lon2):
lon1, lat1, lon2, lat2 = np.radians(lon1), np.radians(lat1), np.radians(lon2), np.radians(lat2)
dlon = lon2 - lon1
dlat = lat2 - lat1
a = np.sin(dlat/2.0)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2.0)**2
return 3958.7613 * 2 * np.arcsin(np.sqrt(a))
def calculate_distance(source_loc, target_locs):
tlat = np.array([t[0] for t in target_locs])
tlon = np.array([t[1] for t in target_lcos])
slat = np.full(tlat.shape, source_loc[0])
slon = np.full(tlon.shape, source_loc[1])
arr = haversine_nb(slat, slon, tlat,tlon)
我想在 DataFrame 中创建另一列,其中包含每个 ID 从源坐标到目标坐标的距离列表。像这样:
ID, Source Coord, Target Coords, Distances(mi)
1, (35, -75), [(30, -72), (31, -71), ...], [5,1, ...]
2, (34, -74), [(50, -50), (45,-45), ...], [10, 2,...]
我知道我可以在 Dataframe 上使用 .apply
函数,但是它非常慢,因为 DataFrame 是 large.I 想知道是否有人知道是否有办法使用矢量化生成这个新列.
使用从源到目标的多对一映射扩展为整齐的格式:
1, (35, -75), [(30, -72), (31, -71), ...]
因此,
ID Source Target
1 (35, -75) (30, -72)
1 (35, -75) (31, -71)
1 (35, -75) ...
然后只需获取源和目标之间的矢量化列的距离。如果您希望它恢复为以 ID 为中心的形式,请将其折叠回列表中。
@ifly6,编辑您的 post 的应用程序,但它似乎是获取此信息的最有效和最合适的方式。请按您认为合适的方式进行编辑。
df_ = df.explode('Target Coords')
lat1, lon1 = map(np.array, zip(*df_['Source Coord']))
lat2, lon2 = map(np.array, zip(*df_['Target Coords']))
haversine_nb(lat1, lon1, lat2, lon2)
我目前有一个 pandas DataFrame 设置如下:
ID, Source Coord, Target Coords
1, (35, -75), [(30, -72), (31, -71), ...]
2, (34, -74), [(50, -50), (45,-45), ...]
源坐标和目标坐标是纬度和经度。我有一个矢量化函数来计算从源到某些目标节点的距离:
from numba import njit
@njit
def haversine_nb(lat1, lon1, lat2, lon2):
lon1, lat1, lon2, lat2 = np.radians(lon1), np.radians(lat1), np.radians(lon2), np.radians(lat2)
dlon = lon2 - lon1
dlat = lat2 - lat1
a = np.sin(dlat/2.0)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2.0)**2
return 3958.7613 * 2 * np.arcsin(np.sqrt(a))
def calculate_distance(source_loc, target_locs):
tlat = np.array([t[0] for t in target_locs])
tlon = np.array([t[1] for t in target_lcos])
slat = np.full(tlat.shape, source_loc[0])
slon = np.full(tlon.shape, source_loc[1])
arr = haversine_nb(slat, slon, tlat,tlon)
我想在 DataFrame 中创建另一列,其中包含每个 ID 从源坐标到目标坐标的距离列表。像这样:
ID, Source Coord, Target Coords, Distances(mi)
1, (35, -75), [(30, -72), (31, -71), ...], [5,1, ...]
2, (34, -74), [(50, -50), (45,-45), ...], [10, 2,...]
我知道我可以在 Dataframe 上使用 .apply
函数,但是它非常慢,因为 DataFrame 是 large.I 想知道是否有人知道是否有办法使用矢量化生成这个新列.
使用从源到目标的多对一映射扩展为整齐的格式:
1, (35, -75), [(30, -72), (31, -71), ...]
因此,
ID Source Target
1 (35, -75) (30, -72)
1 (35, -75) (31, -71)
1 (35, -75) ...
然后只需获取源和目标之间的矢量化列的距离。如果您希望它恢复为以 ID 为中心的形式,请将其折叠回列表中。
@ifly6,编辑您的 post 的应用程序,但它似乎是获取此信息的最有效和最合适的方式。请按您认为合适的方式进行编辑。
df_ = df.explode('Target Coords')
lat1, lon1 = map(np.array, zip(*df_['Source Coord']))
lat2, lon2 = map(np.array, zip(*df_['Target Coords']))
haversine_nb(lat1, lon1, lat2, lon2)