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

如何高效计算两个DataFrame经纬度距离并筛选符合阈值的a表数据

两个经纬度DataFrame高效筛选近邻点位方案

嵌套for循环效率低的核心原因是Python原生循环开销大,且时间复杂度为O(n*m)(n为a的点数、m为b的点数),数据量稍大就会严重卡顿,以下是两种高效实现方案:

方案1:KD树近邻搜索(推荐,大数据量最优)

基于空间索引实现,时间复杂度可降至O(n log m),支持多线程加速,适合千级以上点数的场景,使用scikit-learn的NearestNeighbors实现:

import pandas as pd
import numpy as np
from sklearn.neighbors import NearestNeighbors

# 距离阈值,单位米,根据实际需求修改
X = 500

# 1. 经纬度转弧度(haversine度量要求输入为弧度)
a['lat_rad'] = np.deg2rad(a['LAT'])
a['lon_rad'] = np.deg2rad(a['LONG'])
b['lat_rad'] = np.deg2rad(b['LAT'])
b['lon_rad'] = np.deg2rad(b['LONG'])

# 2. 用b的点位构建半径搜索KD树
R = 6371000 # 地球平均半径,单位米
threshold_rad = X / R
nbrs = NearestNeighbors(radius=threshold_rad, metric='haversine', n_jobs=-1)
nbrs.fit(b[['lat_rad', 'lon_rad']].values)

# 3. 对a的所有点位做半径查询,保留存在至少一个近邻的点位
_, indices = nbrs.radius_neighbors(a[['lat_rad', 'lon_rad']].values)
mask = [len(idx) > 0 for idx in indices]
a_filtered = a[mask].drop(columns=['lat_rad', 'lon_rad']).copy()

方案2:向量化距离计算(小数据量最简)

基于numpy广播机制计算所有点对距离,不需要额外引入机器学习依赖,适合百级点数的场景:

import pandas as pd
import numpy as np

X = 500 # 距离阈值,单位米

# 1. 经纬度转弧度
a_lat, a_lon = np.deg2rad(a['LAT']), np.deg2rad(a['LONG'])
b_lat, b_lon = np.deg2rad(b['LAT']), np.deg2rad(b['LONG'])

# 2. 广播计算所有点对的haversine距离(单位米)
dlat = b_lat[np.newaxis, :] - a_lat[:, np.newaxis]
dlon = b_lon[np.newaxis, :] - a_lon[:, np.newaxis]
a_ = np.sin(dlat / 2)**2 + np.cos(a_lat[:, np.newaxis]) * np.cos(b_lat[np.newaxis, :]) * np.sin(dlon / 2)**2
c = 2 * np.arcsin(np.sqrt(a_))
dist_matrix = 6371000 * c

# 3. 筛选出任意距离小于阈值的a点位
mask = (dist_matrix < X).any(axis=1)
a_filtered = a[mask].copy()

高精度需求补充方案

如果需要和geopy.distance.distance的WGS84椭球计算结果完全对齐,可使用pyproj的向量化计算:

import pandas as pd
import numpy as np
from pyproj import Geod

X = 500 # 距离阈值,单位米

# 初始化WGS84椭球计算器
g = Geod(ellps='WGS84')

# 广播展开所有点对坐标
lons1 = a['LONG'].values[:, np.newaxis].repeat(len(b), axis=1)
lats1 = a['LAT'].values[:, np.newaxis].repeat(len(b), axis=1)
lons2 = b['LONG'].values[np.newaxis, :].repeat(len(a), axis=0)
lats2 = b['LAT'].values[np.newaxis, :].repeat(len(a), axis=0)

# 批量计算距离,返回结果单位为米
_, _, dist_matrix = g.inv(lons1, lats1, lons2, lats2)

mask = (dist_matrix < X).any(axis=1)
a_filtered = a[mask].copy()

以上所有方案的底层运算均为C实现,比原生Python嵌套循环效率高10~1000倍不等,具体提升幅度随数据量增大而升高。

内容的提问来源于stack exchange,提问作者Abhinav Parab

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 09:15:04