2015-11-09 27 views
3

我想提高我對numpy功能的理解。我瞭解numpy.dot的行爲。我想了解numpy.outernumpy.dot方面的行爲。可以使用np.dot生成np.outer的結果嗎?

基於此維基百科文章https://en.wikipedia.org/wiki/Outer_product我期望array_equal在下面的代碼中返回True。但事實並非如此。

X = np.matrix([ 
    [1,5], 
    [5,9], 
    [4,1] 
]) 

r1 = np.outer(X,X) 
r2 = np.dot(X, X.T) 
np.array_equal(r1, r2) 

如何分配r2以使np.array_equal返回True?此外,爲什麼numpy的np.outer的實現不符合Wikipedia上外部乘法的定義?

使用numpy的1.9.2

+0

你對內在和點/轉置之間關係的理解似乎是正確的。你用什麼數據爲'X'?對於簡單的向量和數組,我變爲True。 – wim

+0

感謝您的驗證!剛編輯我的問題以包含輸入數據。 – Selah

+0

對我而言,它仍然返回True –

回答

3
In [303]: X=np.array([[1,5],[5,9],[4,1]]) 
In [304]: X 
Out[304]: 
array([[1, 5], 
     [5, 9], 
     [4, 1]]) 
In [305]: np.inner(X,X) 
Out[305]: 
array([[ 26, 50, 9], 
     [ 50, 106, 29], 
     [ 9, 29, 17]]) 
In [306]: np.dot(X,X.T) 
Out[306]: 
array([[ 26, 50, 9], 
     [ 50, 106, 29], 
     [ 9, 29, 17]]) 

維基外鏈接主要是關於向量會談,一維數組。你的X是2d。

In [310]: x=np.arange(3) 
In [311]: np.outer(x,x) 
Out[311]: 
array([[0, 0, 0], 
     [0, 1, 2], 
     [0, 2, 4]]) 
In [312]: np.inner(x,x) 
Out[312]: 5 
In [313]: np.dot(x,x) # same as inner 
Out[313]: 5 
In [314]: x[:,None]*x[None,:] # same as outer 
Out[314]: 
array([[0, 0, 0], 
     [0, 1, 2], 
     [0, 2, 4]]) 

請注意,Wiki外部不涉及求和。 Inner在此示例中爲5是外部的3個對角線值的總和。

dot也涉及求和 - 所有產品都遵循特定軸上的求和。

一些wiki外層方程使用顯式索引。 einsum函數可以實現這些計算。

In [325]: np.einsum('ij,kj->ik',X,X) 
Out[325]: 
array([[ 26, 50, 9], 
     [ 50, 106, 29], 
     [ 9, 29, 17]]) 
In [326]: np.einsum('ij,jk->ik',X,X.T) 
Out[326]: 
array([[ 26, 50, 9], 
     [ 50, 106, 29], 
     [ 9, 29, 17]]) 
In [327]: np.einsum('i,j->ij',x,x) 
Out[327]: 
array([[0, 0, 0], 
     [0, 1, 2], 
     [0, 2, 4]]) 
In [328]: np.einsum('i,i->',x,x) 
Out[328]: 5 

如在評論中提及,np.outer使用ravel,例如

return a.ravel()[:, newaxis]*b.ravel()[newaxis,:] 

這與我之前爲x演示的廣播乘法相同。

+0

這是一個有趣的關係需要注意,我期待了解外部,但! – Selah

+0

你問'np.outer(X ,X)'? – hpaulj

+0

是的,對不起,我在我的代碼中有一個錯字 – Selah

1

numpy.outer僅適用於1-d矢量,不適用於矩陣。但對於一維矢量的情況,存在一種關係。

如果

import numpy as np 
A = np.array([1.0,2.0,3.0]) 

然後這個

np.matrix(A).T.dot(np.matrix(A)) 

應該是相同的,因爲這

np.outer(A,A) 
0

另一個(笨重)版本類似於a[:,None] * a[None,:]

a.reshape(a.size, 1) * a.reshape(1, a.size) 
相關問題