最稳方案是用 haversine.haversine_vector 批量计算,前提为经纬度是 float64、单位为度、顺序为 [lat, lon];若不能装包,则手写 numpy 向量化版本,注意弧度转换、a 值裁剪及坐标顺序。

直接用 haversine 公式最稳,别碰 geopy.distance.geodesic 做批量计算——它慢、吃内存、还容易因坐标格式报错。
用 haversine.haversine_vector 批量算最高效
这是目前 Pandas 场景下最快、最省内存的方式。前提是你的经纬度列是 float64 类型,且单位是度(不是弧度),顺序是 [lat, lon]。
- 先装库:
pip install haversine - 构造两列坐标数组:用
np.column_stack把df['lat1'], df['lon1']拼成(n, 2)形状的数组,另一组同理 - 调用
haversine.haversine_vector(arr1, arr2, unit='km'),返回一维ndarray,直接赋给新列即可 - 注意:
unit可选'km'、'm'、'mi',别传字符串'kilometers'——会静默失败
自己写 numpy 版 haversine 避免额外依赖
如果不能装第三方包,就手写向量化版本。Pandas + NumPy 原生支持,不慢,还完全可控。
- 所有三角函数输入必须是弧度,用
np.radians()转一次就够了,别在公式里反复转 - 核心四行足够:
dlon = lon2 - lon1,dlat = lat2 - lat1,a = np.sin(dlat/2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2)**2,c = 2 * np.arcsin(np.sqrt(a)) - 地球平均半径取
6371.0km,乘上c就是千米距离 - 要防
sqrt输入负数(浮点误差导致a略大于 1),加一句a = np.clip(a, 0, 1)
别用 geopy.distance.geodesic 处理整列数据
它单次调用精度高,但内部做了大量地理椭球体迭代,每算一对都新建对象,10 万行能卡死、内存涨到几个 GB。
- 错误现象:
TypeError: object of type 'float' has no len()—— 因为传了标量却期望序列 - 有人用
apply+ lambda 包一层,结果比纯 Python 循环还慢 - 它默认单位是米,但返回的是
Distance对象,得显式调.km或.m,否则没法进 Pandas 列 - 真正需要高精度(比如跨极地或超长距离)时,才值得为少量关键点单独调用
球面距离计算本身不难,但批量场景下性能和数值稳定性才是关键。最容易被忽略的是坐标顺序(lat/lon 还是 lon/lat)、单位是否统一、以及浮点误差导致的 sqrt 输入越界——这三个点出错,结果可能差几百米甚至报 NaN。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











