给定特定纬度/经度计算距离纬度/经度

时间:2016-11-22 04:43:19

标签: python csv pandas dataframe euclidean-distance

需要有效的python代码(使用pandas)帮助找到最接近incident_sw =(35.7158,-120.7640)的时间。我在制定欧几里德距离时难以通过下面的df排序并打印哪辆车及其相应的时间最接近incident_sw。所有时间都是HH:MM:SS.SS(假设下面的时间是12小时)。

我的时间转换功能 -

def time_convert(str_time):                                                   
values = str_time.split(':')                                                         
mins = 60*(float(values[0]) - 12) + float(values[1]) + 1.0/60 * float(values[2])     
mins = round(mins, 4)                                                                
return mins    

我的csv数据框 -

vehicle time    lat[D.DDD]  lon[D.DDD]
veh_1   17:19.5 35.7167809  -120.7645652
veh_1   17:19.5 35.7167808  -120.7645652
veh_1   17:19.7 35.7167811  -120.7645648
veh_1   17:20.1 35.7167812  -120.7645652
veh_2   17:20.4 35.7167813  -120.7645647
veh_2   17:20.7 35.7167813  -120.7645646
veh_3   17:22.6 35.7167807  -120.7645651
veh_3   17:23.4 35.7167808  -120.7645652
veh_4   17:24.1 35.7167803  -120.7645653
veh_4   17:25.0 35.7167806  -120.7645658
veh_5   17:25.9 35.7167798  -120.7645659
veh_5   17:26.6 35.7167799  -120.7645658

1 个答案:

答案 0 :(得分:0)

所以,首先,我建议您使用像Geopy这样的库来计算点之间的距离。其次,我建议使用GeoPandas来存储地理信息。稍后会详细介绍。

假设您的距离功能被称为distance(您自己编码,或者根据您的喜好从Geopy获取),这将有助于您加速某些事情。请注意,即使它使用numpy库中的vectorize,下面的实现仍然是一个循环。此外,以下是伪代码,您必须修改它才能为您工作。

import numpy as np

def dist_calc(point, list_of_points):
    dist = np.vectorize(lambda x: distance(point, x))
    return dist(list_of_points)

# Now you can call it simply using:
df['points'] = list(zip(df['lat'], df['lon']))
df.groupby('vehicle')['points'].transform(dist_calc, point=incident_sw)

推荐GeoPandas的原因很简单。如果你有大量的搜索点,比如说每辆车每分钟或每秒留下一点点,那么上面的答案将花费很长时间来计算。如果您要将数据存储在GeoPandas中,则可以使用GeoPandas中的bufferintersects工具来限制事件周围的搜索空间。在这种情况下,您将围绕事件构建合理大小的缓冲区,并仅搜索属于该缓冲区内的那些车辆点。这将有助于加快您的代码。

我建议您在继续操作之前花些时间熟悉GeoPandas的所有功能。

使用geopy中的great_circle

from geopy import great_circle
import numpy as np

def dist_calc(point, list_of_points):
    dist = np.vectorize(lambda x: great_circle(point, x).meters)
    return dist(list_of_points)

# Now you can call it simply using:
df['points'] = list(zip(df['lat'], df['lon']))
df['distances'] = df.groupby('vehicle')['points'].transform(dist_calc, point=incident_sw)