在Python中矢量化Haversine距离计算

前端之家收集整理的这篇文章主要介绍了在Python中矢量化Haversine距离计算前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我正在尝试计算由纬度和经度识别的一长串位置列表的距离矩阵.使用Haversine公式的经度,该公式采用两个坐标对元组来产生距离:

  1. def haversine(point1,point2,miles=False):
  2. """ Calculate the great-circle distance bewteen two points on the Earth surface.
  3. :input: two 2-tuples,containing the latitude and longitude of each point
  4. in decimal degrees.
  5. Example: haversine((45.7597,4.8422),(48.8567,2.3508))
  6. :output: Returns the distance bewteen the two points.
  7. The default unit is kilometers. Miles can be returned
  8. if the ``miles`` parameter is set to True.
  9. """

我可以使用嵌套for循环计算所有点之间的距离,如下所示:

  1. data.head()
  2. id coordinates
  3. 0 1 (16.3457688674,6.30354512503)
  4. 1 2 (12.494749307,28.6263955635)
  5. 2 3 (27.794615136,60.0324947881)
  6. 3 4 (44.4269923769,110.114216113)
  7. 4 5 (-69.8540884125,87.9468778773)

使用简单的功能

  1. distance = {}
  2. def haver_loop(df):
  3. for i,point1 in df.iterrows():
  4. distance[i] = []
  5. for j,point2 in df.iterrows():
  6. distance[i].append(haversine(point1.coordinates,point2.coordinates))
  7. return pd.DataFrame.from_dict(distance,orient='index')

但考虑到时间的复杂性,这需要相当长的一段时间,在20分钟左右运行500分,而且我有更长的清单.这让我看着矢量化,我遇到了numpy.vectorize((docs),但无法弄清楚如何在这种情况下应用它.

最佳答案
您可以将函数作为参数提供给np.vectorize(),然后可以将其用作pandas.groupby.apply的参数,如下所示:

  1. haver_vec = np.vectorize(haversine,otypes=[np.int16])
  2. distance = df.groupby('id').apply(lambda x: pd.Series(haver_vec(df.coordinates,x.coordinates)))

例如,样本数据如下:

  1. length = 500
  2. df = pd.DataFrame({'id':np.arange(length),'coordinates':tuple(zip(np.random.uniform(-90,90,length),np.random.uniform(-180,180,length)))})

比较500分:

  1. def haver_vect(data):
  2. distance = data.groupby('id').apply(lambda x: pd.Series(haver_vec(data.coordinates,x.coordinates)))
  3. return distance
  4. %timeit haver_loop(df): 1 loops,best of 3: 35.5 s per loop
  5. %timeit haver_vect(df): 1 loops,best of 3: 593 ms per loop

猜你在找的Python相关文章