我有一个问题类似于这里提出的问题: 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,则应融合这些点。
在保险丝功能的输出中,最后的点被融合。这看起来像是:
#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]])
答案 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]])
对于大样本,此方法可能会导致内存错误,因为它存储的是包含相对距离的完整矩阵。