如何遍历两个DataFrame并在ID匹配时计算经纬度坐标距离
Pandas匹配ID计算经纬度距离实现方案
首先不建议手动遍历两个DataFrame做匹配,用merge关联的方式性能更高、代码更简洁,实现步骤如下:
步骤1:导入依赖并构造示例数据
import pandas as pd import numpy as np # 构造和问题结构一致的示例数据 df1 = pd.DataFrame({ 'ID': [1], 'Name': ['xyz'], 'lat/long': [(23, 12)] }) df2 = pd.DataFrame({ 'ID': [1], 'Store': ['pharmacy'], 'lat/long': [(23, 13)] })
步骤2:拆分经纬度元组为独立字段
# 拆分df1的经纬度 df1[['lat1', 'lon1']] = pd.DataFrame(df1['lat/long'].tolist(), index=df1.index) # 拆分df2的经纬度 df2[['lat2', 'lon2']] = pd.DataFrame(df2['lat/long'].tolist(), index=df2.index)
步骤3:按ID关联匹配两个表
内连接会自动过滤掉两个表ID不匹配的行,等效于你写的ID相等判断逻辑
merged_df = pd.merge(df1, df2, on='ID', how='inner')
步骤4:批量计算经纬度距离
这里用常用的哈弗辛公式计算地球球面距离,返回单位为千米,如果只需要平面欧式距离可以直接修改计算逻辑:
def haversine(lat1, lon1, lat2, lon2): # 地球平均半径,单位千米 R = 6371.0 # 角度转弧度 lat1_rad = np.radians(lat1) lon1_rad = np.radians(lon1) lat2_rad = np.radians(lat2) lon2_rad = np.radians(lon2) dlat = lat2_rad - lat1_rad dlon = lon2_rad - lon1_rad a = np.sin(dlat / 2)**2 + np.cos(lat1_rad) * np.cos(lat2_rad) * np.sin(dlon / 2)**2 c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1 - a)) return R * c # 一次性计算所有匹配ID的距离 merged_df['distance_km'] = haversine(merged_df['lat1'], merged_df['lon1'], merged_df['lat2'], merged_df['lon2'])
(不推荐)手动遍历实现方案
如果确实需要按遍历的方式实现,可参考以下写法,数据量较大时性能远低于merge方案:
result = [] for _, row1 in df1.iterrows(): for _, row2 in df2.iterrows(): if row1['ID'] == row2['ID']: lat1, lon1 = row1['lat/long'] lat2, lon2 = row2['lat/long'] dist = haversine(lat1, lon1, lat2, lon2) result.append({ 'ID': row1['ID'], 'Name': row1['Name'], 'Store': row2['Store'], 'distance_km': dist }) result_df = pd.DataFrame(result)
注意:如果你的经纬度是GCJ02、BD09等国内坐标系,需要先做坐标系转换再计算距离,否则会有偏差
内容的提问来源于stack exchange,提问作者mohammad zain
相关产品推荐
相关产品推荐

