簡體   English   中英

numpy:如何從矩陣向量構造向量矩陣

[英]numpy: how to construct a matrix of vectors from vector of matrix

我是 numpy 的新手,因此,對於 numpy,是否可以使用矩陣向量來獲取向量矩陣”,例如:

matrix1(  
[  
 [1, 2, 3],  
 [1, 2, 3],  
 [1, 2, 3]  
])

matrix2(  
[  
 [2, 4, 6],  
 [2, 4, 6],  
 [2, 4, 6]  
])

-->

matrix(  
[  
 [array('1 2'), array('2 4'), array('3 6')],  
 [array('1 2'), array('2 4'), array('3 6')],  
 [array('1 2'), array('2 4'), array('3 6')]  
])

我是 numpy 的新手,所以我不確定是否允許在 numpy 的矩陣中放入任何東西或只是數字。 而且從谷歌那里得到答案並不容易,比如“矩陣的向量和矩陣的向量”這樣的描述

numpy沒有與“矩陣”分開的“向量”概念。 它確實有不同的“矩陣”和“數組”概念,但大多數人完全避免使用矩陣表示。 如果使用數組,則“向量”、“矩陣”和“張量”的概念都包含在數組“形狀”屬性的一般概念下。

在這種世界觀中,向量和矩陣都是二維數組,僅通過它們的形狀來區分。 行向量是形狀為(1, n)的數組,而列向量是形狀為(n, 1)數組。 矩陣是形狀為(n, m)數組。 一維數組有時會表現得像向量,這取決於上下文,但通常你會發現除非你“升級”它們,否則你不會得到你想要的。

考慮到所有這些,這里有一個可能的答案來回答您的問題。 首先,我們創建一個一維數組:

>>> a1d = numpy.array([1, 2, 3])
>>> a1d
array([1, 2, 3])

現在我們重塑它以創建一個列向量。 這里的-1告訴numpy找出給定輸入的正確大小。

>>> vcol = a1d.reshape((-1, 1))
>>> vcol
array([[1],
       [2],
       [3]])

請注意開頭和結尾處的雙括號。 這是一個微妙的提示,表明這是一個二維數組,即使一維的大小僅為 1。

我們可以做同樣的事情,交換維度,得到一行。 再次注意雙括號。

>>> vrow = a1d.reshape((1, -1))
>>> vrow
array([[1, 2, 3]])

您可以看出這些是二維數組,因為一維數組的shape元組中只有一個值:

>>> a1d.shape
(3,)
>>> vcol.shape
(3, 1)
>>> vrow.shape
(1, 3)

要從列向量構建矩陣,我們可以使用hstack 還有很多其他方法可能更快,但這是一個很好的起點。 這里,請注意[vcol]不是一個numpy對象,而是一個普通的 python 列表,所以[vcol] * 3[vcol, vcol, vcol]意思相同。

>>> mat = numpy.hstack([vcol] * 3)
>>> mat
array([[1, 1, 1],
       [2, 2, 2],
       [3, 3, 3]])

vstack從行向量中給了我們同樣的東西。

>>> mat2 = numpy.vstack([vrow] * 3)
>>> mat2
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

“從矩陣向量構造向量矩陣”的任何其他解釋都不太可能在numpy生成您真正想要的東西!

既然你提到想要做線性代數,這里有幾個可能的操作。 這假設您使用的是最新版本的 python 來使用新的@運算符,它為數組的矩陣乘法提供了明確的內聯符號。 1

對於數組,乘法始終是按元素進行的。 但有時有廣播。 對於具有相同形狀的值,它是純元素乘法:

>>> vrow * vrow
array([[1, 4, 9]])
>>> vcol * vcol
array([[1],
       [4],
       [9]])

當值具有不同的形狀時,如果可能,它們會一起廣播以產生合理的結果:

>>> vrow * vcol
array([[1, 2, 3],
       [2, 4, 6],
       [3, 6, 9]])
>>> vcol * vrow
array([[1, 2, 3],
       [2, 4, 6],
       [3, 6, 9]])

廣播也以您期望的其他形狀的方式工作:

>>> vrow * mat
array([[1, 2, 3],
       [2, 4, 6],
       [3, 6, 9]])
>>> vcol * mat
array([[1, 1, 1],
       [4, 4, 4],
       [9, 9, 9]])

如果你想要一個點積,你必須使用@操作符:

>>> vrow @ vcol
array([[14]])

請注意,與*運算符不同,這不是對稱的:

>>> vcol @ vrow
array([[1, 2, 3],
       [2, 4, 6],
       [3, 6, 9]])

起初這可能有點令人困惑,因為這看起來與vrow * vcol相同,但不要被愚弄。 *無論參數順序如何,都會產生相同的結果。 最后,對於矩陣向量乘積:

>>> mat @ vcol
array([[ 6],
       [12],
       [18]])

再次觀察@*之間的區別:

>>> mat * vcol
array([[1, 1, 1],
       [4, 4, 4],
       [9, 9, 9]])

1. 遺憾的是,這只存在於 Python 3.5。 如果您需要使用較早的版本,則所有相同的建議都適用,不同之處在於,您必須使用np.dot(a, b)而不是對a @ b使用內聯符號。 numpymatrix類型覆蓋*以表現得像@ ... 但是你不能以相同的方式進行元素乘法或廣播! 所以即使你有更早的版本,我也不建議使用matrix類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM