【发布时间】:2020-09-16 22:38:09
【问题描述】:
我有这样的表格:
import pandas as pd
import numpy as np
df1 = pd.DataFrame([
['A', (37.55, 126.97)],
['B', (37.56, 126.97)],
['C', (37.57, 126.98)]
], columns=['STA_NM', 'COORD'])
df2 = pd.DataFrame([
['A-01', (37.57, 126.99)]
], columns=['ID', 'COORD'])
我正在尝试从df2 中选择每个坐标,并从df1 中找到两个最近的站点(STA_NM) 及其到每个坐标的距离,然后将它们添加到df2 的新列中。我尝试了以下代码:
from heapq import nsmallest
from math import cos, asin, sqrt
def dist(x, y):
p = 0.017453292519943295
a = 0.5 - cos((y[0] - x[0]) * p) / 2 + cos(x[0] * p) * cos(y[0] * p) * (1 - cos((y[1] - x[1]) * p)) / 2
return 12741 * asin(sqrt(a))
def shortest(df, v):
l_sta = []
# get a list of coords
l_coord = df['COORD'].tolist()
# get the two nearest coordinates
near_coord = nsmallest(2, l_coord, key=lambda p: dist(v, p))
# find station names
l_sta.append((df.loc[df['COORD'] == near_coord[0], 'STA_NM'].to_string(index=False), round(dist(near_coord[0], v) * 1000)))
l_sta.append((df.loc[df['COORD'] == near_coord[1], 'STA_NM'].to_string(index=False), round(dist(near_coord[1], v) * 1000)))
# e.g.: [('A', 700), ('B', 1000)]
return l_sta
df2['NEAR_STA'] = df2['COORD'].map(lambda x: shortest(df1, x))
在原始数据中,df1 大约有 700 行,df2 大约有 55k 行。当我尝试上述代码时,花了将近两分钟。有没有更好的方法让它更快?
【问题讨论】:
-
“最快的方式”可能要先进得多。但这个问题至少已经在 3d 点上得到了处理:stackoverflow.com/questions/4350215/…
-
我相信 SciPy 有
scipy.spatial.KDTree来处理这种情况。 -
还记得有 RTree 可能会有所帮助,但我不确定:pypi.org/project/Rtree
标签: python python-3.x pandas