如何在数据框列中查找第一个和最后一个元素并修剪这些元素之间的值

问题描述 投票:2回答:1

我一直在使用坐标数据。 (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)]
python python-3.x pandas
1个回答
1
投票

这里是我的解决方案:例如,我使用库geopy计算距离。

您可以选择使用geodesic()或great_circle()计算距离,即函数distance = geodesic。并且您可以将指标.km更改为.milesmft(如果您希望使用其他指标)

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
© www.soinside.com 2019 - 2024. All rights reserved.