python - 对haversine公式使用列表推导
问题描述
我有两个数据框。房屋位置之一和餐厅位置之一,其坐标均以纬度/经度为单位。我需要创建一个新列来计算它们之间的距离。例如,如果我有一个包含 5 个房屋位置的列表,则预期结果将是每个餐厅的 5 次距离计算(25 个值)。df1 是位置,df2 是餐厅。
我的距离计算在这里,但我确实改变了几次:
版本 1:
def distance(location, restaurant):
lat1, lon1 = location
lat2, lon2 = restaurant
radius = 6371 *1000# km
dlat = math.radians(lat2-lat1)
dlon = math.radians(lon2-lon1)
a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(lat1)) \
* math.cos(math.radians(lat2)) * math.sin(dlon/2) * math.sin(dlon/2)
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
d = radius * c
return d
版本 2:
def haversine(lat1, lon1, lat2, lon2):
radius = 6371
dlat = math.radians(lat2-lat1)
dlon = math.radians(lon2-lon1)
a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(lat1)) \
* math.cos(math.radians(lat2)) * math.sin(dlon/2) * math.sin(dlon/2)
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
d = radius * c
return d
我试过写一个循环,但它返回'Series object is not callable'错误:
ll = []
for index,rows in df2.iterrows():
lat1 = rows['Latitude']
lon1 = rows['Longitude']
for i,r in df1.iterrows():
dist = distance((lat1,lon1),(r['Latitude'],r['Longitude']))
ll.append(rows(float(dist)))
然后我尝试使用列表推导,两种不同的方式:
df1['result'] = df1.apply(lambda x: float(haversine(df1['Latitude'], df1['Longitude'], df2['Latitude'], df2['Longitude']), axis=1))
第一个返回错误“无法将系列转换为 <class 'float'>
第二个没有给我我正在寻找的结果:
Dist = []
for w, x, y, z in zip(df1['Latitude'], df2['Longitude'], df2['Latitude'], df2['Longitude']):
Dist.extend([distance((w,x),(y,z))])
print(Dist)
output: [515.38848499753, 54.26312420254462, 10.563518031233743, 374.5045129388741, 451.6737920301973]
这样做的正确方法是什么?最终,我将不得不将其扩展到 10 万间房屋和 2480 间餐厅。不幸的是,我无权共享数据。
解决方案
您可以使用运行速度更快的矢量化操作,这是一个片段,它采用两个维度为 nX2、mX2 的数组,即保存 n 和 m 个位置
import numpy as np
from sklearn.metrics.pairwise import haversine_distances
def haversine(locations1, locations2):
locations1 = np.deg2rad(locations1)
locations2 = np.deg2rad(locations2)
return haversine_distances(locations1, locations2) * 6371000
使用您的尺寸,它会在 10 秒内在我的机器上运行
推荐阅读
- ckan - CKAN:上传大型资源文件不成功
- c# - 如何使用datagridview列检查sql中是否存在行
- r - 如何防止 R 系统命令语法错误
- sql - 如何强制 Postgres 以数值精度计算
- c# - 添加列表
作为现有列表的新元组 > - sql - Django ORM 二进制精确
- google-chrome - 如何从 Chrome 访问 github.com/lucas-clemente/quic-go 服务器?
- jwt - 我有模数和指数如何使用 JavaScript 为某些有效负载生成 JWE
- c# - 如何在值对象中删除值对象 [DDD]
- javascript - VueJS:未捕获的类型错误:vue__WEBPACK_IMPORTED_MODULE_4__.default 不是构造函数