在 python 中,如果x,y是向量,我希望x @ y.T給我 x 和 y 的外積,即匹配np.outer(x,y). 然而,令我驚訝的是,x @ y.T它回傳一個標量。為什么?向量(即一維陣列)是否不被 numpy 視為列向量?
例如,代碼
import numpy as np
x=np.array([1,2])
y=np.array([3,4])
wrong_answer = x @ y.T
right_answer = np.outer(x,y)
給出(互動式)輸出
In [1]: wrong_answer
Out[1]: 11
In [2]: right_answer
Out[2]:
array([[3, 4],
[6, 8]])
uj5u.com熱心網友回復:
取@點積,而不是外積。
使用您在代碼中定義的變數:
>>> x=np.array([1,2])
>>> y=np.array([3,4])
>>> np.dot(x,y)
11
你得到 11,這是使用 '@' 生成的點積
編輯:討論更新
基于這個答案以及通過PEP465挖掘,@操作員__matmul__在引擎蓋下使用,這也是點積。
>>> x.__matmul__(y)
11
uj5u.com熱心網友回復:
“向量(即一維陣列)是否不被 numpy 視為列向量? ” -> 不,您需要添加一個維度。并且@是點積,而不是乘法。
你需要:
x[:,None]*y
輸出:
array([[3, 4],
[6, 8]])
您可以檢查轉置一維陣列是否不會改變任何內容:
y.T
array([3, 4])
uj5u.com熱心網友回復:
np.transpose,np.dot并且np.matmul在給定一維陣列時都記錄了它們的行為。 broadcasting理解也是一件好事。
你的兩個陣列都是一維的:
In [250]: x=np.array([1,2])
...: y=np.array([3,4])
In [251]: x.shape
Out[251]: (2,)
transpose不改變一維陣列的維度;它不添加維度。它只是對現有維度重新排序:
In [252]: y.T.shape
Out[252]: (2,)
outer明確表示它適用于一維陣列(以及其他陣列):
In [254]: np.outer(x,y)
Out[254]:
array([[3, 4],
[6, 8]])
作為一個長期numpy用戶,我更喜歡使用廣播乘法:
In [255]: x[:,None]*y # (n,1)*(m) => (n,1)*(1,m) => (n,m)
Out[255]:
array([[3, 4],
[6, 8]])
outer也將其動作比作np.einsum,但我現在將跳過它。
dot/matmul明確說明它對一維陣列的作用:
In [256]: np.dot(x,y) # dot of 1d arrays is inner product
Out[256]: 11
In [257]: np.matmul(x,y) # x@y
Out[257]: 11
broadcasting不適@/matmul用于(對于最后 2 個維度,即):
In [260]: x[:,None]@y
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Input In [260], in <cell line: 1>()
----> 1 x[:,None]@y
ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 2 is different from 1)
但是 (n,1) 與 (1,m) => (n,m),共享大小為 1 維度作為乘積之和維度:
In [261]: x[:,None]@y[None,:]
Out[261]:
array([[3, 4],
[6, 8]])
在這種情況下,使用廣播乘法做同樣的事情:
In [262]: x[:,None]*y[None,:] # "column vector" * "row vector"
Out[262]:
array([[3, 4],
[6, 8]])
另一種控制維度的方法是使用np.einsum:
In [263]: np.einsum('i,i',x,y)
Out[263]: 11
In [264]: np.einsum('i,j',x,y)
Out[264]:
array([[3, 4],
[6, 8]])
In [265]: np.einsum('i,i->i',x,y) # x*y
Out[265]: array([3, 8])
因為一維陣列確實如此,而不是變相的行/列向量,我們可能需要在這里或那里添加一個維度來匹配我們在 MATLAB 等面向矩陣的語言中看到的行為。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/526390.html
上一篇:PythonNump:隨機種子
下一篇:嘗試遍歷陣列并注釋它們
