You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pandas中无需循环高效实现逐行跨行运算的方法

实现思路

你当前使用的逐行for循环效率低下,本质是没有利用numpy的向量化广播能力,且pandas逐行取数的索引开销会随数据量增长被放大。完全不需要写显式循环,通过数组维度扩展做批量计算,一次就能得到所有点对的haversine距离,运算速度可以提升2~3个数量级。

注意:你提供的原始代码存在参数顺序错误:haversine_np定义时第一个入参是经度lon1,但循环调用时第一个传入的是纬度值,会导致计算结果完全错误,下述实现已修正该问题。

向量化实现代码
import numpy as np
import pandas as pd

def batch_haversine(lon_arr, lat_arr):
    # 提前统一将角度转为弧度,避免重复计算
    lon_rad = np.radians(lon_arr)
    lat_rad = np.radians(lat_arr)
    
    # 扩展数组维度,利用广播机制一次性生成所有点对的经纬度差
    dlon = lon_rad[:, np.newaxis] - lon_rad[np.newaxis, :]
    dlat = lat_rad[:, np.newaxis] - lat_rad[np.newaxis, :]
    
    # 批量计算所有点对的haversine中间值
    a = np.sin(dlat / 2.0)**2 + np.cos(lat_rad[:, np.newaxis]) * np.cos(lat_rad[np.newaxis, :]) * np.sin(dlon / 2.0)**2
    c = 2 * np.arcsin(np.sqrt(a))
    
    # 返回n*n的距离矩阵,单位为公里,matrix[i,j]对应第i个点到第j个点的距离
    return 6367 * c

# 加载你的示例数据
d1 = {'id': [1, 2, 3, 4, 5, 6, 7, 8, 9], 'longitude': [4.929783, 4.932333, 4.933950, 4.933900, 4.928467, 4.924583, 4.922133, 4.921400, 4.920967], 'latitude': [52.372250, 52.370884, 52.371101, 52.372234, 52.375282, 52.375950, 52.376301, 52.376232, 52.374481]}
df = pd.DataFrame(data=d1)

# 一次计算得到所有点对的距离,无Python层面的显式循环
distance_matrix = batch_haversine(df['longitude'].to_numpy(), df['latitude'].to_numpy())

# 如果需要和原表ID做映射,可以转为带索引的DataFrame
distance_df = pd.DataFrame(
    distance_matrix,
    index=df['id'],
    columns=df['id']
)
超大数据量适配提示

如果你的数据集点数超过10万,全量n*n距离矩阵会占用极高内存(10万点对应1e10个矩阵元素,单精度浮点存储需要约40GB内存),这种场景不要强行计算全矩阵:

  • 如果你的需求是查找每个点周边固定半径内的近邻,直接使用scipy.spatial.cKDTree构建空间索引做球面近邻查询,内存占用和运算速度都远优于全量距离计算
  • 如果必须输出全量点对距离,可以按行分块计算,每次仅计算部分行与全量点的距离,逐块写入存储避免内存溢出

内容的提问来源于stack exchange,提问作者Zubayer Islam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 07:06:10