2012-03-14 149 views
3

我有一个N点(N * 3)的3D坐标的数组X,并且想要计算每对点之间的eukledian距离。如何在numPy中执行此操作?

我可以遍历X,并将其与阈值进行比较做到这一点。

coords = array([v.xyz for v in vertices]) 
for vertice in vertices: 
    tests = np.sum(array(coords - vertice.xyz) ** 2, 1) < threshold 
    closest = [v for v, t in zip(vertices, tests) if t] 

这是可能在一个操作中做?我记得10年前的线性代数,找不到一种方法来做到这一点。

也许这应该是一个3D阵列(点A,点B,轴),然后通过axis尺寸相加。

编辑:我自己找到了解决方案,但它不适用于大数据集。

coords = array([v.xyz for v in vertices]) 
    big = np.repeat(array([coords]), len(coords), 0) 
    big_same = np.swapaxes(big, 0, 1) 
    tests = np.sum((big - big_same) ** 2, 0) < thr_square 

    for v, test_vector in zip(vertices, tests): 
     v.closest = self.filter(vertices, test_vector) 

回答

2

使用scipy.spatial.distance。如果X是点的n×3阵列,则可以从

from scipy.spatial import distance 
D = distance.squareform(distance.pdist(X)) 

然后得到一个n×n距离矩阵,最接近点i是与索引点

np.argsort(D[i])[1] 

(该[1]跳过对角线的价值,将首先返回。)

+0

它能保持70k点吗? – 2012-03-14 19:49:50

+1

@culebrón:不要介意我以前的评论(现在删除)。这个规模的问题是记忆;距离矩阵需要GB。但是,如果您不使用'scipy.spatial.distance',问题将是CPU时间。你需要做什么距离? – 2012-03-14 19:58:09

+0

我需要从每个阈值中找出点,以将它们聚类。 – 2012-03-14 20:02:28

0

我不太清楚你在这里问什么。如果要计算N点空间中每对点之间的欧几里德距离,将结果表示为查找矩阵对我来说是有意义的。所以对于N点,你会得到一个NxN对称矩阵。元素(3,5)将表示点3和5之间的距离,而元素(2,2)将是点2和它自身之间的距离(零)。这是我会怎么做随机点:

import numpy as np 

N = 5 

coords = np.array([np.random.rand(3) for _ in range(N)]) 
dist = np.zeros((N, N)) 

for i in range(N): 
    for j in range(i, N): 
     dist[i, j] = np.linalg.norm(coords[i] - coords[j]) 
     dist[j, i] = dist[i, j] 

print dist 
+0

这不是我所需要的,因为我测试了CPROFILE的算法。 linalg.norm非常慢。周期也非常缓慢。 np.arrays的批量操作速度一样快。 – 2012-03-14 18:37:34

+0

你指的是什么样的批量操作? – 2012-03-14 19:15:33

+0

'np.sum(array(coords - vertice.xyz)** 2,1) 2012-03-14 19:49:18

0

如果xyz是与你的坐标的数组,然后将下面的代码将计算距离矩阵(工作速度快,直到那一刻,当你有足够的内存来存储N^2距离):

xyz = np.random.uniform(size=(1000,3)) 
distances = (sum([(xyzs[:,i][:,None]-xyzs[:,i][None,:])**2 for i in range(3)]))**.5 
相关问题