【发布时间】:2021-08-31 17:54:18
【问题描述】:
我有两个数据框。房屋位置之一和餐厅位置之一,其坐标均以纬度/经度为单位。我需要创建一个新列来计算它们之间的距离。例如,如果我有一个包含 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))
第一个返回错误'cannot convert the series to
第二个没有给我想要的结果:
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 家餐厅。很遗憾,我没有共享数据的权限。
【问题讨论】:
-
当你扩大规模时,结果将有 2.48 亿个条目。您可能应该找到一种优化它的方法 - 可能只是按街道或社区进行优化,而不是获取每个房子的距离。
-
ll.append(rows(float(dist)))应该是ll.append(dist)。您为什么要尝试将rows用作函数? -
@Barmar 我的错误,我可以删除那个错字。 & 我同意,但是,我不负责这个项目,我只是想完成对我的要求
标签: python pandas dataframe list-comprehension haversine