按接近程度对一组点进行分组

时间:2014-02-16 05:20:51

标签: python algorithm google-maps data-structures geometry

我有几千个点表示为纬度和经度的2D浮点阵列。

(42.385305, -87.963793)
(41.703427, -88.121665)
(41.889764, -87.978553)
(41.995931, -87.787501)
(42.25875, -87.948199)
              .
              .
              .

在这个集合中,纬度的最小值和最大值分别为34.03176和42.470814,经度的最小值和最大值分别为-118.238819和-87.598201。

我想将这些点分为0.025纬度和0.03经度的区域,然后考虑每个区域一次,对每个区域的点进行一些计算和操作。

或者,如果我能找到两个或多个点位置太紧密的区域,比如半径3公里范围内,情况会好得多。

我曾想过使用哈希映射或2D数组,但是设置有效密钥或引用正确的区域将会很棘手。

R树可能不合适,因为它的建筑很复杂而且效率不高,特别是考虑到我不需要随机访问。正如我上面提到的,我正在逐个遍历每个区域。

这样做的有效方法是什么?

1 个答案:

答案 0 :(得分:2)

如果您完全向量化距离计算,那么几千点不应该花那么长时间:

In [1]:
from numpy import *
In [3]:
def lg_lat_distance(p1,p2): #based on Spherical Law of Cosines
    lg1=p1[0] #data format, (latitude, longitude)
    la1=p1[1]
    lg2=p2[0]
    la2=p2[1]
    return arccos(sin(la1)*sin(la2)+cos(la1)*cos(la2)*cos(lg1-lg2))*6371 #in km
In [14]:
data=array([(42.385305, -87.963793),
            (41.703427, -88.121665),
            (41.889764, -87.978553),
            (41.995931, -87.787501),
            (42.25875, -87.948199)]) #5 elements
data=data/180*pi
In [16]:
dist_matrix=(lg_lat_distance(hstack([data,]*5).reshape(-1,2).T, vstack([data,]*5).T)).reshape(5,5)
print dist_matrix

[[  9.49352980e-05   1.77442357e+01   2.54929710e+00   1.96682533e+01
    1.80515399e+00]
 [  1.77442357e+01   0.00000000e+00   1.59289162e+01   3.71753501e+01
    1.94041828e+01]
 [  2.54929710e+00   1.59289162e+01   0.00000000e+00   2.12484793e+01
    3.67668607e+00]
 [  1.96682533e+01   3.71753501e+01   2.12484793e+01   0.00000000e+00
    1.79018035e+01]
 [  1.80515399e+00   1.94041828e+01   3.67668607e+00   1.79018035e+01
    9.49352980e-05]]

In [17]:
%timeit dist_matrix=(lg_lat_distance(hstack([data,]*5).reshape(-1,2).T, vstack([data,]*5).T)).reshape(5,5)
1000 loops, best of 3: 245 µs per loop

我认为事情会变得容易dist_matrix。您可以使用成对距离<5 km使用布尔索引过滤出对。或者您可以运行群集分析。