2017-04-12 327 views
1

如何用該行的單位向量劃分numpy數組的每個行元素?將numpy矩陣的每個元素除以該行的單位向量

對於例如:

A = np.array([[ 0. , 1.],[ 2., 4.],[ 1., 5.]]) 

所以,需要輸出矩陣應該是:

[[ 0.0 , 1.][0.0, 0.0][0.19611614 , 0.98058068]] 

我通過使用下面的片段而獲得的:

for row in A: 
    t=np.sqrt(np.sum(row**2)) 
    row = row/t 

但是,當我使用此代碼在我的非常大的矩陣上拋出錯誤: 「RuntimeWarning:invalid value enco沒有在true_divide「。但我沒有任何無效的值在我的numpy」A「數組中。我使用「argwhere」檢查進行檢查。它總是返回一個空列表。這個矩陣要麼有0個值,要麼有些值。我知道應該有一些更容易執行這個計算。請幫助。

回答

0

這裏有一個方法 -

from __future__ import division 

dists = np.linalg.norm(A,axis=1,keepdims=1) 
out = np.where(np.isclose(dists,0), 0, A/dists) 

基本上,np.where我們兩個選項之間進行選擇,語法之中:

np.where(condition, option1, option2) 

爲了避免任何警告,並寫回結果輸入,使用面具 -

mask = ~np.isclose(dists,0).ravel() 
A[mask] /= dists[mask] 

說明on:對於布爾數組condition中的每個數組元素,它將在兩個數組option1option2中的相應元素之間進行選擇。在我們的例子中,如果使用np.isclose檢測到dists元素接近於零,這表示該行中的所有元素都是與該dists值相對應的所有零。因此,本質上,如果conditionzero,我們將0作爲輸出,否則選擇計算出的dist值作爲輸出。


幾乎別無選擇得到distsnp.sumnp.einsum性能 -

np.sqrt(np.einsum('ij,ij->i',A,A))[:,None] 
np.sqrt((A**2).sum(1))[:,None] 

einsum基本計算平方而且隨着np.einsum('ij,ij->i',A,A)第二軸sum-reduction。其餘的只是square-root,並添加一個新的軸與[:,None]對齊和後來的分裂對A

沿着第二軸,sum的後面的方法基本上是squaringsummingnp.sum。其餘部分與einsum相同。

+0

你能告訴我爲什麼它給了我這個警告嗎? –

+0

@NikitaGupta可能因爲你被'0'分隔。輸入數組的數據類型是什麼? – Divakar

+0

@NikitaGupta我認爲它是因爲你有一個零值元素,'norm'值也是'0'。所以,對於那個'0/0'分區,它可能會拋出這個警告。 – Divakar

相關問題