numpy-2d中的近点快速融合(没有for循环)

时间:2016-05-02 14:41:40

标签: python arrays numpy scipy distance

我有一个问题类似于这里提出的问题: simple way of fusing a few close points。我想用它们的坐标平均值替换彼此靠近的点。细胞的接近程度由用户指定(我说的是欧几里德距离)。

在我的情况下,我有很多积分(约100万)。这种方法很有效,但是因为它使用了一个双循环来节省时间。

是否有更快的方法来检测和融合numpy 2d阵列中的近点?

为了完成,我添加了一个例子:

points=array([[  382.49056159,   640.1731949 ],
   [  496.44669161,   655.8583119 ],
   [ 1255.64762859,   672.99699399],
   [ 1070.16520917,   688.33538171],
   [  318.89390168,   718.05989421],
   [  259.7106383 ,   822.2       ],
   [  141.52574427,    28.68594436],
   [ 1061.13573287,    28.7094536 ],
   [  820.57417943,    84.27702407],
   [  806.71416007,   108.50307828]])

下面可以看到点的散点图。红色圆圈表示彼此靠近的点(在这种情况下,阵列中最后两个点之间的距离为27.91)。因此,如果用户指定最小距离为30,则应融合这些点。

enter image description here

在保险丝功能的输出中,最后的点被融合。这看起来像是:

#output
array([[  382.49056159,   640.1731949 ],
   [  496.44669161,   655.8583119 ],
   [ 1255.64762859,   672.99699399],
   [ 1070.16520917,   688.33538171],
   [  318.89390168,   718.05989421],
   [  259.7106383 ,   822.2       ],
   [  141.52574427,    28.68594436],
   [ 1061.13573287,    28.7094536 ],
   [  813.64416975,    96.390051175]])

2 个答案:

答案 0 :(得分:7)

如果您有大量积分,那么使用k-D tree构建scipy.spatial.cKDTree可能会更快,然后查询它们是否接近某个阈值的点数:

ComponentsList

此方法的主要优点是您无需计算数据集中每对点之间的距离。

答案 1 :(得分:1)

您可以使用scipy的距离函数,例如pdist,以便快速找到应合并的点:

import numpy as np
from scipy.spatial.distance import pdist, squareform

d = squareform(pdist(a))
d = np.ma.array(d, mask=np.isclose(d, 0))
a[d.min(axis=1) < 30]
#array([[ 820.57417943,   84.27702407],
#       [ 806.71416007,  108.50307828]])

对于大样本,此方法可能会导致内存错误,因为它存储的是包含相对距离的完整矩阵。