我有一个 数据帧 与 > 2.7mm的坐标,和一个单独的 列表 中 〜2000坐标 。我试图返回 与列表中的每个坐标 相比,
每一 行中 的坐标之间的最小距离。以下代码在较小的规模(具有200行的数据框)上工作,但是在计算2.7MM以上的行时,它似乎可以永远运行。
from haversine import haversine
df
Latitude Longitude
39.989 -89.980
39.923 -89.901
39.990 -89.987
39.884 -89.943
39.030 -89.931
end_coords_list = [(41.342,-90.423),(40.349,-91.394),(38.928,-89.323)]
for row in df.itertuples():
def min_distance(row):
beg_coord = (row.Latitude, row.Longitude)
return min(haversine(beg_coord, end_coord) for end_coord in end_coords_list)
df['Min_Distance'] = df.apply(min_distance, axis=1)
我知道问题在于正在发生的大量计算(5.7MM * 2,000 =〜11.4BN),以及运行这么多循环的效率低得令人难以置信。
根据我的研究,似乎矢量化NumPy函数可能是一种更好的方法,但是我是Python和NumPy的新手,所以我不确定在这种特殊情况下如何实现此功能。
理想输出:
df
Latitude Longitude Min_Distance
39.989 -89.980 3.7
39.923 -89.901 4.1
39.990 -89.987 4.2
39.884 -89.943 5.9
39.030 -89.931 3.1
提前致谢!
的haversine func
本质是:
# convert all latitudes/longitudes from decimal degrees to radians
lat1, lng1, lat2, lng2 = map(radians, (lat1, lng1, lat2, lng2))
# calculate haversine
lat = lat2 - lat1
lng = lng2 - lng1
d = sin(lat * 0.5) ** 2 + cos(lat1) * cos(lat2) * sin(lng * 0.5) ** 2
h = 2 * AVG_EARTH_RADIUS * asin(sqrt(d))
这是一种利用强大功能NumPy broadcasting
并NumPy ufuncs
替换那些数学模块功能的矢量化方法,以便我们可以一次性处理整个数组-
# Get array data; convert to radians to simulate 'map(radians,...)' part
coords_arr = np.deg2rad(coords_list)
a = np.deg2rad(df.values)
# Get the differentiations
lat = coords_arr[:,0] - a[:,0,None]
lng = coords_arr[:,1] - a[:,1,None]
# Compute the "cos(lat1) * cos(lat2) * sin(lng * 0.5) ** 2" part.
# Add into "sin(lat * 0.5) ** 2" part.
add0 = np.cos(a[:,0,None])*np.cos(coords_arr[:,0])* np.sin(lng * 0.5) ** 2
d = np.sin(lat * 0.5) ** 2 + add0
# Get h and assign into dataframe
h = 2 * AVG_EARTH_RADIUS * np.arcsin(np.sqrt(d))
df['Min_Distance'] = h.min(1)
为了进一步提高性能,我们可以使用numexpr
模块来代替先验功能。
运行时测试和验证
方法-
def loopy_app(df, coords_list):
for row in df.itertuples():
df['Min_Distance1'] = df.apply(min_distance, axis=1)
def vectorized_app(df, coords_list):
coords_arr = np.deg2rad(coords_list)
a = np.deg2rad(df.values)
lat = coords_arr[:,0] - a[:,0,None]
lng = coords_arr[:,1] - a[:,1,None]
add0 = np.cos(a[:,0,None])*np.cos(coords_arr[:,0])* np.sin(lng * 0.5) ** 2
d = np.sin(lat * 0.5) ** 2 + add0
h = 2 * AVG_EARTH_RADIUS * np.arcsin(np.sqrt(d))
df['Min_Distance2'] = h.min(1)
验证-
In [158]: df
Out[158]:
Latitude Longitude
0 39.989 -89.980
1 39.923 -89.901
2 39.990 -89.987
3 39.884 -89.943
4 39.030 -89.931
In [159]: loopy_app(df, coords_list)
In [160]: vectorized_app(df, coords_list)
In [161]: df
Out[161]:
Latitude Longitude Min_Distance1 Min_Distance2
0 39.989 -89.980 126.637607 126.637607
1 39.923 -89.901 121.266241 121.266241
2 39.990 -89.987 126.037388 126.037388
3 39.884 -89.943 118.901195 118.901195
4 39.030 -89.931 53.765506 53.765506
时间-
In [163]: df
Out[163]:
Latitude Longitude
0 39.989 -89.980
1 39.923 -89.901
2 39.990 -89.987
3 39.884 -89.943
4 39.030 -89.931
In [164]: %timeit loopy_app(df, coords_list)
100 loops, best of 3: 2.41 ms per loop
In [165]: %timeit vectorized_app(df, coords_list)
10000 loops, best of 3: 96.8 µs per loop
我有一个多边形类型的几何体,我正在计算一个点的最小距离可能在多边形几何体内部(由360个点组成,作为闭合几何体)或多边形几何体外部。使用postgis的ST_distance方法,当点在几何体外部时,我得到精确的距离,但如果点在几何体内部,则得到0作为距离,我想要与多边形几何体最近点的点之间的最小距离,无论该点位于几何体内部还是外部。
问题内容: 我正在尝试使用Haversine公式来计算由纬度和经度标识的一长串位置的距离矩阵,该公式采用两个坐标对的元组来产生距离: 我可以使用嵌套的for循环计算所有点之间的距离,如下所示: 使用一个简单的函数: 但是考虑到时间的复杂性,这需要花费相当长的时间,大约需要20秒才能获得500点,而且我的清单要长得多。这让我着眼于矢量化,并且遇到了((docs)),但无法弄清楚如何在这种情况下应用它
问题内容: 我对如何尽可能快地以numpy计算距离有疑问, 结果在以下时间: 虽然最后一个给出的是sqrt((VVm-VVs)^ 2 +(HHm-HHs)^ 2),而其他的给出的是(VVm-VVs)^ 2 +(HHm-HHs)^ 2,但这并不是很重要,因为否则在我的代码中,我将为每个i取R [i ,:]的最小值,而sqrt无论如何都不会影响最小值,(如果我对距离感兴趣,我只需取sqrt(value
问题内容: 我有一个工作的PHP脚本,该脚本获取经度和纬度值,然后将它们输入到MySQL查询中。我只想将其制作成MySQL。这是我当前的PHP代码: 有谁知道如何完全使用MySQL?我浏览了一下互联网,但是关于它的大多数文献都令人困惑。 问题答案: 来自Google Code常见问题解答-使用PHP,MySQL和Google Maps创建商店定位器 : 这是一条SQL语句,它将找到距离37,-12
问题内容: 继一些在线调查(1,2,numpy的,SciPy的,scikit,数学),我已经找到了计算的几种方法 在Python欧氏距离 : 我想知道是否有人可以就 效率* 和 精度 方面认为上述哪一项( 或我未找到的其他任何 理由)提供最佳见解。如果有人知道任何的 资源(S) ,其中讨论的主题,这也将是巨大的。 *** __ 的 背景下 ,我在有趣的是,在计算对数元组之间的欧氏距离,例如之间的距
问题内容: 我在二维空间中有一组点,需要计算每个点到另一个点的距离。 我的点数相对较少,最多不超过100个。但是,由于我需要经常快速地确定这些移动点之间的关系,并且因为我知道遍历这些点可能同样糟糕由于O(n ^ 2)的复杂性,我正在寻找利用numpy矩阵魔术(或scipy)的方法。 就象我的代码中所说的那样,每个对象的坐标都存储在其类中。但是,当我更新类坐标时,也可以用numpy数组更新它们。 我
我想用Optaplanner解决VRP问题(添加一些内容)。在文档中,人们经常说,预先计算位置之间的距离,然后对每个位置使用
问题内容: 我正在使用Hibernate检索特定查询的行数。假设我有一个名为“ Person”的表,其中包含各种列。这些列之一是“名称”。 如果我想获得带有“安德鲁”名字的人数,以下哪种方法最有效?假设某些/全部之间存在性能差异。使用Hibernate / SQL是否有更好的方法? (1)选择所有列 (2)仅选择名称列 (3)在查询中使用Count (4)在查询中的名称列中使用Count 编辑:对