python - numpy 矩阵向量乘法

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

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

示例代码如下:

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

我想要的是:

print a*b
   >>
   [16 6 8]

最佳答案

最简单的解决方案

使用 numpy.dota.dot(b)。请参阅文档 here .

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

这是因为 numpy 数组不是矩阵,而标准操作 *、+、-、/ 在数组上按元素工作。

请注意,虽然您可以使用 numpy.matrix (截至 2021 年初)在 * 将被视为标准矩阵乘法的情况下,numpy.matrix 已弃用,可能会在未来的版本中删除。强>。见 the note in its documentation (转载如下):

It is no longer recommended to use this class, even for linear algebra. Instead use regular arrays. The class may be removed in the future.

感谢@HopeKing。


其他解决方案

还知道还有其他选择:

  • 如下所述,如果使用 python3.5+ 和 numpy v1.10+,@ 操作符会像你期望的那样工作:

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

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

    >>> np.matmul(a, b)
    array([16, 6, 8])
    
  • numpy.inner功能与 numpy.dot 矩阵向量乘法相同,但行为不同矩阵矩阵和张量乘法(参见维基百科关于 the inner product and dot product 之间的差异)或see this SO answer 关于 numpy 的实现)。

    >>> 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]])
    
  • 如果你有多个二维数组dot,你可以考虑np.linalg.multi_dot函数,它简化了许多嵌套 np.dot 的语法。请注意,这只适用于二维数组(即不适用于矩阵向量乘法)。

      >>> np.dot(np.dot(a, a.T), a).dot(a.T)
      array([[1406,  382,  446],
             [ 382,  106,  126],
             [ 446,  126,  152]])
      >>> np.linalg.multi_dot((a, a.T, a, a.T))
      array([[1406,  382,  446],
             [ 382,  106,  126],
             [ 446,  126,  152]])
    

边缘情况的稀有选项

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

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

https://stackoverflow.com/questions/21562986/

相关文章:

python - 如何将 SqlAlchemy 结果序列化为 JSON?

linux - 如何获取 Linux/UNIX 上当前的网络接口(interface)吞吐量统计信息

python - glob.glob() 的返回值是如何排序的?

linux - 什么 linux shell 命令返回字符串的一部分?

linux - cd进入目录没有权限

python - 在python中跳过for循环的第一个条目?

python - pip 安装 : Please check the permissions and

python - "hashable"在 Python 中是什么意思?

linux - 带有 -i 选项的 sed 命令(就地编辑)在 Ubuntu 上运行良好,但在 Ma

linux - Linux Bash 中的双与号 (&&) 和分号 (;) 有什么区别?