1 回答

TA貢獻1854條經驗 獲得超8個贊
這是我的解決方案:我使用庫 geopy 來計算距離。
您可以選擇在 geodesic() 或 great_circle() 中計算距離,函數 distance = geodesic。
你可以在度量標準更改.km到.miles或m或ft如果你喜歡別的指標
from geopy.distance import lonlat, distance, great_circle,geodesic
dmin=[]
for index, r in df_actual.iterrows():
valmin = df_fleet.apply(lambda x:
distance(lonlat(x['Longitude'], x['Latitude']),
lonlat(r['Longitude'], r['Latitude'])).km,axis=1).min()
dmin.append(valmin)
df_actual['nearest to fleet(km)'] = dmin
print(df_actual)
如果你想要所有艦隊點 < 100m 每個實際點,你做
for ai, a in df_actual.iterrows():
actual = lonlat(a['Longitude'], a['Latitude'])
filter = df_fleet.apply(lambda x:
distance(lonlat(x['Longitude'], x['Latitude']), actual).meters < 100 ,axis=1)
print(f"for {(a['Longitude'], a['Latitude'])}"); print(df_fleet[filter])
最后一個解決方案基于樹計算,我認為它非常非??欤艺谑褂?scipy 空間,它計算空間中的最近點并給出歐幾里得距離的結果。我剛剛調整了 x,y,z 空間點中的 lat,lon 以獲得正確的結果(測地線或半正弦)。在這里,我生成了 2 個(緯度,經度)15000 和 10000 行的數據幀,我正在為 df2 中的每個 df1 搜索五個最近的數據幀
from random import uniform
from math import radians, sin, cos
from scipy.spatial import cKDTree
import pandas as pd
import numpy as np
def to_cartesian(lat, lon):
lat = radians(lat); lon = radians(lon)
R = 6371
x = R * cos(lat) * cos(lon)
y = R * cos(lat) * sin(lon)
z = R * sin(lat)
return x, y , z
def newpoint():
return uniform(23, 24), uniform(66, 67)
def ckdnearest(gdA, gdB, bcol):
nA = np.array(list(zip(gdA.x, gdA.y, gdA.z)) )
nB = np.array(list(zip(gdB.x, gdB.y, gdB.z)) )
btree = cKDTree(nB)
dist, idx = btree.query(nA,k=5) #search the first 5 (k=5) nearest point df2 for each point of df1
dist = [d for d in dist]
idx = [s for s in idx]
df = pd.DataFrame.from_dict({'distance': dist,
'index of df2' : idx})
return df
#create the first df (actual)
n = 15000
lon,lat = [],[]
for x,y in (newpoint() for x in range(n)):
lon += [x];lat +=[y]
df1 = pd.DataFrame({'lat': lat, 'lon': lon})
df1['x'], df1['y'], df1['z'] = zip(*map(to_cartesian, df1.lat, df1.lon))
#-----------------------
#create the second df (fleet)
n = 10000
lon,lat = [],[]
for x,y in (newpoint() for x in range(n)):
lon += [x];lat +=[y]
id = [x for x in range(n)]
df2 = pd.DataFrame({'lat': lat, 'lon': lon})
df2['x'], df2['y'], df2['z'] = zip(*map(to_cartesian, df2.lat, df2.lon))
#-----------------------
df = ckdnearest(df1, df2, 'unused')
print(df)
如果你只想要 1 個沒有笛卡爾坐標的最近點:
def ckdnearest(gdA, gdB, bcol):
nA = np.array(list(zip(gdA.lat, gdA.lon)))
nB = np.array(list(zip(gdB.lat, gdB.lon)))
btree = cKDTree(nB)
dist, idx = btree.query(nA,k=1) #search the first nearest point df2
df = pd.DataFrame.from_dict({'distance': dist, 'index of df2' : idx})
return df
添加回答
舉報