numpy:如何从矩阵向量构造向量矩阵

时间:2017-06-15 17:27:05

标签: python numpy matrix vector

我是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的矩阵中或只是数字。 并且从谷歌获得答案并不容易,例如“矩阵向量和矩阵向量”

1 个答案:

答案 0 :(得分:0)

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]])

你可以知道这些是2-d数组,因为1-d数组在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中。如果您需要使用早期版本,则会应用所有相同的建议,但不是使用a @ b的内联表示法,而是必须使用np.dot(a, b)numpy的{​​{1}}类型会覆盖matrix,表现得像* ...但是您不能以相同的方式进行逐元素乘法或广播!因此,即使您有早期版本,我也不建议使用@类型。