【问题标题】:numpy: how to construct a matrix of vectors from vector of matrixnumpy:如何从矩阵的向量构造向量矩阵
【发布时间】:2017-11-18 07:12:05
【问题描述】:

我是 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 matrix 而不是 2d 或 3d np.ndarray?主要区别在于 NumPy 矩阵的乘法遵循通常的线性代数规则,而如果将两个兼容形状的 2d ndarray 相乘,则会得到元素乘法。如果你不做线性代数,你几乎肯定想要一个 ndarray 而不是矩阵。
  • 您要解决的更大的问题是什么?您可以做很多与此大致相似的事情,但我怀疑这不是要问的正确问题。部分困难在于 numpy 没有与“矩阵”分开的“向量”概念。它确实有“矩阵”和“数组”的不同概念,但大多数人完全避免使用矩阵表示。如果使用数组,“向量”、“矩阵”和“张量”的概念都包含在数组“形状”属性的一般概念下。
  • @MarkDickinson 我正在尝试按元素进行线性代数。也就是说,对于最终矩阵的一个元素,例如。 array('1 2') ,我想将它乘以一个矩阵('1 0,0 1') 并将其乘以另一个数组,例如 transpose(array('1 2'))
  • @senderle 我正在尝试用 numpy 做一些线性代数。还在学习中

标签: python numpy matrix vector


【解决方案1】:

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 类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多