如何使用hasrsine距离矩阵返回满足距离阈值标准的所有点对

时间:2018-06-07 16:52:15

标签: python pandas dataframe haversine

我有39,803个不同的拉特隆点(这里是前5个点)

lat lon
0   27.269987   -82.497004
1   27.537598   -82.508422
2   27.337793   -82.533753
3   27.497719   -82.570261
4   27.512062   -82.722158

我已经计算了

的半正距离矩阵
array([[  0.        ,  29.77832527,   8.36846516, ...,  30.07072193,
      7.60700598,   7.63477669],
   [ 29.77832527,   0.        ,  22.35749757, ...,   2.6836159 ,
     22.17639199,  23.07090099],
   [  8.36846516,  22.35749757,   0.        , ...,  23.07825172,
      3.10333262,   0.75441483],
   ..., 
   [ 30.07072193,   2.6836159 ,  23.07825172, ...,   0.        ,
     22.53766911,  23.75965211],
   [  7.60700598,  22.17639199,   3.10333262, ...,  22.53766911,
      0.        ,   3.03795035],
   [  7.63477669,  23.07090099,   0.75441483, ...,  23.75965211,
      3.03795035,   0.        ]])
因此,我的矩阵是39,803乘39,803。我想弄清楚找到距离小于25米的所有对的方法。例如,如果我们考虑第一个数组

[  0.        ,  29.77832527,   8.36846516, ...,  30.07072193,
  7.60700598,   7.63477669]

这对

(lat[0],lon[0])-(lat[2],lon[2])=(27.269987,-82.497004)-(27.337793,-82.533753) = 8.36846516

满足此标准,但

(lat[0],lon[0])-(lat[1],lon[1])=(27.269987,-82.497004)-(27.537598,-82.508422) = 29.77832527

没有。我想得到满足这个标准的一个子集。这就是我到目前为止所做的:

X=df[['lat','lon']].dropna(axis=0) 
coors=np.array(X)

from math import radians, cos, sin, asin, sqrt

from scipy.spatial.distance import pdist, squareform
from sklearn.cluster import DBSCAN

import matplotlib.pyplot as plt
import pandas as pd


def haversine(lonlat1, lonlat2):

    lat1, lon1 = lonlat1
    lat2, lon2 = lonlat2
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 
    r = 6371 # Radius of earth in kilometers. Use 3956 for miles
    return c * r

distance_matrix = squareform(pdist(X, (lambda u,v: haversine(u,v))))

我非常感谢有关如何计算这个

的任何帮助

1 个答案:

答案 0 :(得分:0)

如何使用numpy.argwhere()功能?这可用于查找满足特定标准的矩阵中条目的行/列索引。 在您的情况下,这可能是这样的:

numpy.argwhere(distances < 25)

这将返回一个Nx2数组,给出N个点的行/列索引,它们之间的距离小于25米。 显然,您可能需要一些额外的过滤来避免与对称距离矩阵相关的重复,并消除每个点与其自身之间的零距离。也许你可以通过获取距离矩阵并执行以下转换来处理它:

distances = distances + 26 * (numpy.tril(numpy.ones_like(distances), k=1))

强制对角线和距离矩阵的上三角形中的所有元素都具有高于25米阈值的值。

在您的特定情况下,因为您在所有点对上隐式使用for循环来计算距离矩阵,所以使用numpy例程来完成最终操作可能无法获得更多过滤阶段。相反,你可能会考虑更像:

indices = [ (i, j) for i in range(Npoints)
                     for j in range(i+1, Npoints)
                     if haversine(points[i], points[j]) < minDistance ]

这种方法虽然不如纯粹的numpy方法那么高效,但是当应用于大量的点时,应该减少内存消耗。

混合方法可能涉及获取点列表的子集,在每对子集之间形成距离矩阵,并使用上述numpy.argwhere()方法对其进行过滤。