Edw*_*ung 7 python numpy vectorization coordinates geopy
我正在尝试从一个数据框计算测地距离,该数据框由四列经纬度数据组成,大约有 300 万行。我使用了 apply lambda 方法来完成它,但完成任务花了 18 分钟。有没有办法将矢量化与 NumPy 数组一起使用来加速计算?谢谢你的回答。
我使用 apply 和 lambda 方法的代码:
from geopy import distance
df['geo_dist'] = df.apply(lambda x: distance.distance(
(x['start_latitude'], x['start_longitude']),
(x['end_latitude'], x['end_longitude'])).miles, axis=1)
Run Code Online (Sandbox Code Playgroud)
更新:
我正在尝试这段代码,但它给了我错误:ValueError:具有多个元素的数组的真值不明确。使用 a.any() 或 a.all()。感谢有人可以提供帮助。
df['geo_dist'] = distance.distance(
(df['start_latitude'].values, df['start_longitude'].values),
(df['end_latitude'].values, df['end_longitude'].values)).miles
Run Code Online (Sandbox Code Playgroud)
我认为您可能会考虑geopandas为此使用它,它是 Pandas(因此numpy)的扩展,旨在非常快速地进行这些类型的计算。
具体来说,它有一种计算 a 中点集之间距离的方法GeoSeries,可以是 a 的一列GeoDataFrame。我相当确定这种方法可以numexpr用于矢量化。
它应该看起来像这样,您可以将数据框转换为GeoDataFrame具有(至少)两GeoSeries列可用于起点和终点的列。这应该返回一个GeoSeries对象:
import pandas as pd
import geopandas as gpd
from shapely.geometry import Point
geometry = [Point(xy) for xy in zip(df.longitude, df.latitude)]
gdf = gpd.GeoDataFrame(df, crs={'init': 'epsg:4326'}, geometry=geometry)
distances = gdf.geometry.distance(gdf.destination_geometry)
Run Code Online (Sandbox Code Playgroud)
你的问题的答案:你不能做你想做的事geopy。我不熟悉这个包,但错误回溯表明这个函数以及可能这个包中的所有其他函数都不是在编写/设计时考虑到矢量化计算的。
现在,如果您可以处理大圆距离,那么我建议您尝试使用astropy.coordinates能够separations以矢量方式计算点之间的包。
这是一个基于我对不同问题的回答的示例:查找最近点:
from astropy.units import Quantity
from astropy.coordinates import SkyCoord, EarthLocation
from astropy.constants import R_earth
import numpy as np
lon1 = Quantity([-71.312796, -87.645307, -87.640426, -87.635513,
-87.630629, -87.625793 ], unit='deg')
lat1 = Quantity([41.49008, 41.894577, 41.894647, 41.894713,
41.894768, 41.894830], unit='deg')
lon2 = Quantity([-81.695391, -87.645307 + 0.5, -87.640426, -87.635513 - 0.5,
-87.630629 + 1.0, -87.625793 - 1.0], unit='deg')
lat2 = Quantity([41.499498, 41.894577 - 0.5, 41.894647, 41.894713 - 0.5,
41.894768 - 1.0, 41.894830 + 1.0], unit='deg')
pts1 = SkyCoord(EarthLocation.from_geodetic(lon1, lat1, height=R_earth).itrs, frame='itrs')
pts2 = SkyCoord(EarthLocation.from_geodetic(lon2, lat2, height=R_earth).itrs, frame='itrs')
Run Code Online (Sandbox Code Playgroud)
然后,两组点之间的距离可以计算为:
>>> dist = pts2.separation(pts1)
>>> print(dist)
<Angle [ 7.78350849, 0.62435354, 0., 0.62435308, 1.25039805, 1.24353876] deg>
Run Code Online (Sandbox Code Playgroud)
距离的近似转换:
>>> np.deg2rad(pts2.separation(pts1)) * R_earth / u.rad
<Quantity [ 866451.17527216, 69502.31527953, 0. ,
69502.26348614, 139192.86680148, 138429.29874024] m>
Run Code Online (Sandbox Code Playgroud)
geopy将第一个值与从示例中获得的值进行比较:
>>> distance.distance((41.49008, -71.312796), (41.499498, -81.695391)).meters
866455.4329098687
Run Code Online (Sandbox Code Playgroud)
编辑:实际上,这很可能实际上会给您所追求的测地距离,但请务必检查 的描述EarthLocation。
| 归档时间: |
|
| 查看次数: |
2321 次 |
| 最近记录: |