我一直在使用坐标数据。 (Lat&Long)
背景
Act Df =
Index Latitude Longitude
0 66.36031097267725 23.714807357485936
1 66.36030099322495 23.71479548193769
2
.
.
Flt Df =
Index Latitude Longitude
0 66.34622070356742 23.687960586306179
1 66.34620931053996 23.687951092116624
2
.
.
len(Actual) = 12053
len(Fleet) = 8000
以上数据显示,在实际数据纬度和经度图中,车队数据坐标点的区域较短。
注意:
车队纬度和经度值可能不一定等于实际纬度和经度值,但是在实际纬度/经度图点中其区域更短
需求
我想根据车队纬度/经度数据中的值来修剪实际纬度/经度数据的一部分。
我的要求是,当我在开放式街道地图或matplotlib中进行绘制时,实际纬度/经度数据和机群纬度/经度数据必须遵循相同的路径。(位置不一定相同)
我尝试过的事情:
我使用过算术运算,如
actual_data[(actual_data['Latitude'] <= fleet_data_Lat_start_point) & (actual_data['Longitude'] <= fleet_data_Long_start_point) & (actual_data['Latitude'] <= fleet_data_Lat_end_point) & (actual_data['Longitude'] <= fleet_data_Long_end_point)]
这里是我的解决方案:例如,我使用库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)
如果您希望所有机队点>
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])
最后一个解决方案基于Tree calcul,我认为它非常非常非常快我正在使用scipy空间,该空间计算空间中的最近点并以欧几里得距离给出结果。我刚刚修改了x,y,z空间点中的经纬度以得到正确的结果(在测地线或正弦线中)。在这里,我生成2个(lat,lon)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)
如果您只希望有一个没有笛卡尔坐标的最近点:
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