2014-10-17 64 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