如何在Python DataFrame中逐行计算地理坐标点间的距离
解决方法
不需要逐行遍历,用Pandas的shift()方法获取相邻行坐标,配合地理计算工具就能高效实现,以下是三种可行方案:
方案1:手动实现Haversine公式(规避包导入问题)
如果haversine包导入失败,直接手动实现球面距离公式更稳妥:
import pandas as pd import numpy as np # 示例DataFrame,X为经度、Y为纬度 df = pd.DataFrame({ 'X': [116.3972, 116.4072, 116.4172], 'Y': [39.9075, 39.9175, 39.9275] }) def haversine(lon1, lat1, lon2, lat2): # 角度转弧度 lon1, lat1, lon2, lat2 = map(np.radians, [lon1, lat1, lon2, lat2]) # 计算坐标差值 dlon = lon2 - lon1 dlat = lat2 - lat1 # Haversine核心计算 a = np.sin(dlat/2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2)**2 c = 2 * np.arcsin(np.sqrt(a)) # 地球平均半径(千米),换成6371000则单位为米 r = 6371 return c * r # 获取下一行的坐标 df['next_X'] = df['X'].shift(-1) df['next_Y'] = df['Y'].shift(-1) # 批量计算相邻点距离 df['dist'] = haversine(df['X'], df['Y'], df['next_X'], df['next_Y']) # 最后一行距离设为0 df.loc[df.index[-1], 'dist'] = 0 # 可选:删除临时生成的辅助列 df = df.drop(['next_X', 'next_Y'], axis=1)
方案2:使用geopy工具
先安装依赖:pip install geopy,再用其内置的距离计算功能:
import pandas as pd from geopy.distance import distance df = pd.DataFrame({ 'X': [116.3972, 116.4072, 116.4172], 'Y': [39.9075, 39.9175, 39.9275] }) # geopy要求坐标格式为(纬度, 经度),生成当前行和下一行的坐标对 coords_current = list(zip(df['Y'], df['X'])) coords_next = coords_current[1:] + [(None, None)] # 计算距离,默认单位为千米,可指定meters/feet等 df['dist'] = [distance(curr, next_).km if next_ != (None, None) else 0 for curr, next_ in zip(coords_current, coords_next)]
方案3:使用pyproj(高精度椭球距离)
适合需要精准椭球地球模型的场景,先安装依赖:pip install pyproj
import pandas as pd from pyproj import Geod import numpy as np df = pd.DataFrame({ 'X': [116.3972, 116.4072, 116.4172], 'Y': [39.9075, 39.9175, 39.9275] }) # 使用WGS84椭球(GPS通用坐标系) geod = Geod(ellps='WGS84') # 获取相邻行的经纬度数组 lon1, lat1 = df['X'].values, df['Y'].values lon2, lat2 = df['X'].shift(-1).values, df['Y'].shift(-1).values # 计算距离(单位为米),返回值包含方位角和距离 _, _, dists = geod.inv(lon1[:-1], lat1[:-1], lon2[:-1], lat2[:-1]) # 拼接结果,最后一行补0 df['dist'] = np.append(dists, 0) # 如需转千米:df['dist'] = np.append(dists/1000, 0)
内容的提问来源于stack exchange,提问作者Connor Garrett
相关产品推荐
相关产品推荐

