我有纬度和经度的数据,我需要计算包含位置的两个数组之间的距离矩阵。我用这个This得到给定经纬度的两个位置之间的距离。
下面是我的代码示例:
import numpy as np
import math
def get_distances(locs_1, locs_2):
n_rows_1 = locs_1.shape[0]
n_rows_2 = locs_2.shape[0]
dists = np.empty((n_rows_1, n_rows_2))
# The loops here are inefficient
for i in xrange(n_rows_1):
for j in xrange(n_rows_2):
dists[i, j] = get_distance_from_lat_long(locs_1[i], locs_2[j])
return dists
def get_distance_from_lat_long(loc_1, loc_2):
earth_radius = 3958.75
lat_dif = math.radians(loc_1[0] - loc_2[0])
long_dif = math.radians(loc_1[1] - loc_2[1])
sin_d_lat = math.sin(lat_dif / 2)
sin_d_long = math.sin(long_dif / 2)
step_1 = (sin_d_lat ** 2) + (sin_d_long ** 2) * math.cos(math.radians(loc_1[0])) * math.cos(math.radians(loc_2[0]))
step_2 = 2 * math.atan2(math.sqrt(step_1), math.sqrt(1-step_1))
dist = step_2 * earth_radius
return dist
我的预期产出是:
>>> locations_1 = np.array([[34, -81], [32, -87], [35, -83]])
>>> locations_2 = np.array([[33, -84], [39, -81], [40, -88], [30, -80]])
>>> get_distances(locations_1, locations_2)
array([[ 186.13522573, 345.46610882, 566.23466349, 282.51056676],
[ 187.96657622, 589.43369894, 555.55312473, 436.88855214],
[ 149.5853537 , 297.56950329, 440.81203371, 387.12153747]])
性能对我来说很重要,我可以做的一件事是使用Cython
来加速循环,但如果不必这样做的话,那就太好了。
有没有一个模块可以做这样的事情?或者其他解决办法?
这只是将代码矢量化:
如果我们看一下时间安排:
对于一个小例子来说,它实际上要慢一些;但是,让我们来看一个更大的例子:
我们现在有40倍的加速速度。可能在一些地方可以挤出更多的速度。
编辑:进行了一些更新以删除多余的位置,并明确表示我们不会更改原始位置数组。
使用meshgrid替换double for循环时更有效:
哈弗辛方程中有很多次优的东西。你可以删去其中的一些,并最小化你需要计算的正弦、余弦和平方根的数量。以下是我所能想到的最好的方法,在我的系统中,在1000和2000个元素的两个随机数组中,运行速度比Ophion代码快5倍(在矢量化方面,Ophion代码的运行速度基本相同):
如果你把你的两个数组“原样”给它,它会抱怨,但这不是一个bug,而是一个特性。基本上,这个函数计算球体上最后一个维度上的距离,并在其余维度上广播。所以你可以得到你想要的:
但它也可用于计算两个点列表之间的距离,即:
或者在两点之间:
这灵感来自于gufuncs的工作原理,一旦你习惯了它,我发现它是一种很棒的“瑞士军刀”编码风格,可以让你在很多不同的设置中重用单个函数。
相关问题 更多 >
编程相关推荐