如何加快熊猫的地理距离计算?

问题描述

我是Pandas / Python入门者,我不知道如何加快我的代码的速度。 我有一个分类的Pandas数据框,称为test,具有约10.000行和多列,包括纬度和经度。我想知道每行附近有多少其他行(在一个阈值的距离内,即10公里以内)。

我尝试这样做:

import numpy as np
def distance(lat1,lon1,lat2,lon2,to_radians=True,earth_radius=6371):

    lat1,lon2 = np.radians([lat1,lon2])

    a = np.sin((lat2-lat1)/2.0)**2 + \
        np.cos(lat1) * np.cos(lat2) * np.sin((lon2-lon1)/2.0)**2

    return earth_radius * 2 * np.arcsin(np.sqrt(a))

和:

["Number_of_neighbours"] = 0
distance = 5
i = 0
y = 0 
for i in range(0,len(test)):
 for y in range(0,len(test)):
 x = haversine(lat1 = test['latitude'].loc[i],lon1 = test['longitude'].loc[i],lat2 = test['latitude'].loc[y],lon2 = test['longitude'].loc[y])
 
 if x <= distance and x != 0:  
  test.at[i,'Number_of_neighbours']= 1 + test.loc[i,'Number_of_neighbours']
  

但是Jupyter永远需要计算结果。您有什么建议或更高效的解决方案吗? 提前非常感谢您!

解决方法

由于数据不太大,您可以重写distance函数以利用numpy的广播功能

def haversine(lat1,lon1,lat2,lon2,to_radians=True,earth_radius=6371):
    lat1,lon2 = np.radians([lat1,lon2])

    a = np.sin((lat2-lat1[:,None])/2.0)**2 + \
        np.cos(lat2) * np.cos(lat1[:,None]) * np.sin((lon2[:,None]-lon1)/2.0)**2

    return earth_radius * 2 * np.arcsin(np.sqrt(a))

distance = 5
dist = haversine(test['latitude'],test['longitude'],test['latitude'],test['longitude'])

test['neighbors'] = (dist < distance).sum(-1)

我的系统在10000行上花费了大约7秒钟的时间。