Python numpy 矩阵向量乘法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21562986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 23:08:27  来源:igfitidea点击:

numpy matrix vector multiplication

pythonarraysnumpyvectormatrix

提问by user3272574

When I multiply two numpy arrays of sizes (n x n)*(n x 1), I get a matrix of size (n x n). Following normal matrix multiplication rules, a (n x 1) vector is expected, but I simply cannot find any information about how this is done in Python's Numpy module.

当我将两个大小为 (nxn)*(nx 1) 的 numpy 数组相乘时,我得到一个大小为 (nxn) 的矩阵。按照正常的矩阵乘法规则,需要一个 (nx 1) 向量,但我在 Python 的 Numpy 模块中找不到任何有关如何完成此操作的信息。

The thing is that I don't want to implement it manually to preserve the speed of the program.

问题是我不想手动实现它以保持程序的速度。

Example code is shown below:

示例代码如下所示:

a = np.array([[ 5, 1 ,3], [ 1, 1 ,1], [ 1, 2 ,1]])
b = np.array([1, 2, 3])

print a*b
   >>
   [[5 2 9]
   [1 2 3]
   [1 4 3]]

What i want is:

我想要的是:

print a*b
   >>
   [16 6 8]

采纳答案by wflynny

Simplest solution

最简单的解决方案

Use numpy.dotor a.dot(b). See the documentation here.

使用numpy.dota.dot(b)。请参阅此处的文档。

>>> a = np.array([[ 5, 1 ,3], 
                  [ 1, 1 ,1], 
                  [ 1, 2 ,1]])
>>> b = np.array([1, 2, 3])
>>> print a.dot(b)
array([16, 6, 8])

This occurs because numpy arrays are not matrices, and the standard operations *, +, -, /work element-wise on arrays. Instead, you could try using numpy.matrix, and *will be treated like matrix multiplication.

发生这种情况是因为 numpy 数组不是矩阵,并且标准操作*, +, -, /在数组上按元素工作。相反,您可以尝试使用numpy.matrix,*并将被视为矩阵乘法。



Other Solutions

其他解决方案

Also know there are other options:

还知道还有其他选择:

  • As noted below, if using python3.5+ the @operator works as you'd expect:

    >>> print(a @ b)
    array([16, 6, 8])
    
  • If you want overkill, you can use numpy.einsum. The documentation will give you a flavor for how it works, but honestly, I didn't fully understand how to use it until reading this answerand just playing around with it on my own.

    >>> np.einsum('ji,i->j', a, b)
    array([16, 6, 8])
    
  • As of mid 2016 (numpy 1.10.1), you can try the experimental numpy.matmul, which works like numpy.dotwith two major exceptions: no scalar multiplication but it works with stacks of matrices.

    >>> np.matmul(a, b)
    array([16, 6, 8])
    
  • numpy.innerfunctions the same way as numpy.dotfor matrix-vector multiplication but behaves differentlyfor matrix-matrix and tensor multiplication (see Wikipedia regarding the differences between the inner product and dot productin general or see this SO answerregarding numpy's implementations).

    >>> np.inner(a, b)
    array([16, 6, 8])
    
    # Beware using for matrix-matrix multiplication though!
    >>> b = a.T
    >>> np.dot(a, b)
    array([[35,  9, 10],
           [ 9,  3,  4],
           [10,  4,  6]])
    >>> np.inner(a, b) 
    array([[29, 12, 19],
           [ 7,  4,  5],
           [ 8,  5,  6]])
    
  • 如下所述,如果使用 python3.5+,该@运算符将按您的预期工作:

    >>> print(a @ b)
    array([16, 6, 8])
    
  • 如果你想要矫枉过正,你可以使用numpy.einsum. 该文档将让您了解它的工作原理,但老实说,直到阅读此答案并自己玩弄它之前,我才完全了解如何使用它。

    >>> np.einsum('ji,i->j', a, b)
    array([16, 6, 8])
    
  • 从 2016 年年中(numpy 1.10.1)开始,您可以尝试实验性的numpy.matmul,它的工作原理numpy.dot与两个主要例外类似:没有标量乘法,但它适用于矩阵堆栈。

    >>> np.matmul(a, b)
    array([16, 6, 8])
    
  • numpy.inner以与numpy.dot矩阵向量乘法相同的方式运行,对于矩阵矩阵和张量乘法的行为不同(请参阅维基百科关于内积和点积之间一般差异或查看有关 numpy 实现的SO 答案)。

    >>> np.inner(a, b)
    array([16, 6, 8])
    
    # Beware using for matrix-matrix multiplication though!
    >>> b = a.T
    >>> np.dot(a, b)
    array([[35,  9, 10],
           [ 9,  3,  4],
           [10,  4,  6]])
    >>> np.inner(a, b) 
    array([[29, 12, 19],
           [ 7,  4,  5],
           [ 8,  5,  6]])
    


Rarer options for edge cases

边缘情况的罕见选项

  • If you have tensors (arrays of dimension greater than or equal to one), you can use numpy.tensordotwith the optional argument axes=1:

    >>> np.tensordot(a, b, axes=1)
    array([16,  6,  8])
    
  • Don't use numpy.vdotif you have a matrix of complex numbers, as the matrix will be flattened to a 1D array, then it will try to find the complex conjugate dot product between your flattened matrix and vector (which will fail due to a size mismatch n*mvs n).

  • 如果您有张量(维度大于或等于 1 的数组),则可以使用numpy.tensordot可选参数axes=1

    >>> np.tensordot(a, b, axes=1)
    array([16,  6,  8])
    
  • numpy.vdot如果您有一个复数矩阵,请不要使用,因为该矩阵将被展平为一维数组,然后它会尝试找到展平后的矩阵和向量之间的复共轭点积(由于大小不匹配而失败)n*mn)。