2014-10-17 43 views
2

python有没有一种快速的方法来执行一个简单的操作,导致一个矩阵,使得给出两个数组a和b(长度相同,但这很可能是A[i,j] = a[i] - b[j] )不相关)?优化简单的向量操作(python)

更确切地说,我所拥有的是二维空间中的N个点,其位置存储在两个数组dx和dy中,N个点的位置在tx和ty中。 我需要一个矩阵

A[i,j] = (dx[j]-tx[i])**2+(dy[j]-ty[i])**2 

我想到的是做

A = np.empty([nData,nData]) 
for i in range(nData): 
     A[i] = (dx-tx[i])**2+(dy-ty[i])**2 
return A 

的问题是,这是太慢的唯一途径(n数据将是大)。如果速度更快,任何符号的更改都会受到欢迎。

(顺便说一句,比X * X或同等慢X ** 2?)

+0

请出示的数据的,最小的,例如和预期的结果。 – wwii 2014-10-17 17:20:35

回答

2

要计算所有成对平方的点之间的欧氏距离。如果你想自己做,在numpy的

>>> import numpy as np 
>>> from scipy.spatial.distance import cdist 
>>> x = np.random.rand(10, 2) 
>>> t = np.random.rand(8, 2) 

>>> cdist(x, t, 'sqeuclidean') 
array([[ 0.61048982, 0.04379578, 0.30763149], 
     [ 0.02709455, 0.30235292, 0.25135934], 
     [ 0.21249888, 0.14024951, 0.28441688], 
     [ 0.39221412, 0.01994213, 0.17699239]]) 

:最快的办法是使用scipy.distance.cdist。这样的事情应该做的伎俩:

>>> np.sum((x[:, None] - t)**2, axis=-1) 
array([[ 0.61048982, 0.04379578, 0.30763149], 
     [ 0.02709455, 0.30235292, 0.25135934], 
     [ 0.21249888, 0.14024951, 0.28441688], 
     [ 0.39221412, 0.01994213, 0.17699239]]) 

或者,使用单独的阵列X和Y坐标:

>>> dx, dy = x.T 
>>> tx, ty = t.T 

>>> (dx[:, None] - tx)**2 + (dy[:, None] - ty)**2 
array([[ 0.61048982, 0.04379578, 0.30763149], 
     [ 0.02709455, 0.30235292, 0.25135934], 
     [ 0.21249888, 0.14024951, 0.28441688], 
     [ 0.39221412, 0.01994213, 0.17699239]]) 
+0

谢谢!奇迹般有效。 – Bzazz 2014-10-20 09:20:08

2

尝试

>>> a = arange(1, 10) 
>>> b = arange(1, 10) 
>>> a.reshape(9, 1) - b.reshape(1, 9) 
array([[ 0, -1, -2, -3, -4, -5, -6, -7, -8], 
     [ 1, 0, -1, -2, -3, -4, -5, -6, -7], 
     [ 2, 1, 0, -1, -2, -3, -4, -5, -6], 
     [ 3, 2, 1, 0, -1, -2, -3, -4, -5], 
     [ 4, 3, 2, 1, 0, -1, -2, -3, -4], 
     [ 5, 4, 3, 2, 1, 0, -1, -2, -3], 
     [ 6, 5, 4, 3, 2, 1, 0, -1, -2], 
     [ 7, 6, 5, 4, 3, 2, 1, 0, -1], 
     [ 8, 7, 6, 5, 4, 3, 2, 1, 0]]) 

发生了什么事在文档片断被称为broadcasting,看该网页上为了解释。如果你不惜一切代价避免显式循环,那么Numpy通常是最快的。谷歌搜索“numpy矢量化”应该为您提供详细信息。

翻译成你的榜样,完整的公式是

(dx.reshape(len(dx), 1) - tx.reshape(1, len(tx)))**2 + \ 
(dy.reshape(len(dy), 1) - ty.reshape(1, len(ty)))**2