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

标签 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

我已经计算了 haversine 距离矩阵

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 x 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))))

如果能帮助我计算这个,我将不胜感激

最佳答案

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

numpy.argwhere(distances < 25)

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

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

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

在您的特定情况下,因为您在所有点对上隐式使用 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() 方法过滤它们。

关于python - 如何使用 haversine 距离矩阵返回满足距离阈值标准的所有点对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50746528/

相关文章:

python - 循环遍历占位符来创建 pandas 系列

python - 在 Pandas 中,当使用 read_csv() 时,如何将 NaN 分配给不是预期 dtype 的值?

python - 覆盖函数内部的全局变量不适用于 Spyder 4

python - 列字典值到单独的 Dataframe

python - 转换数据帧(转置)

python - Python的Threading模块的处理顺序

python - 将列系列中的值替换为值为 1 的相应行

python : imported packages with 'nested' modules

python - 动态模块创建

python - 如何将 Python Flask 应用程序部署到在 Amazon Linux EC2 实例上运行的 Apache (Httpd)