当我将两个大小为(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。点或a.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])

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

注意,虽然可以使用numpy。矩阵(从2021年初开始),其中*将被视为标准矩阵乘法,numpy。矩阵已弃用,可能会在未来的版本中删除。见其文件中的说明(下文转载):

不再推荐使用这个类,即使是线性代数。相反,请使用常规数组。该类将来可能会被删除。

谢谢@HopeKing。


其他的解决方案

也要知道还有其他选择:

As noted below, if using python3.5+ and numpy v1.10+, 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 answer and 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.dot with two major exceptions: no scalar multiplication but it works with stacks of matrices. >>> np.matmul(a, b) array([16, 6, 8]) numpy.inner functions the same way as numpy.dot for matrix-vector multiplication but behaves differently for matrix-matrix and tensor multiplication (see Wikipedia regarding the differences between the inner product and dot product in general or see this SO answer regarding 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]]) If you have multiple 2D arrays to dot together, you may consider the np.linalg.multi_dot function, which simplifies the syntax of many nested np.dots. Note that this only works with 2D arrays (i.e. not for matrix-vector multiplication). >>> 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]])


边缘情况的罕见选项

如果有张量(维数大于或等于1的数组),可以使用numpy。带有可选参数axes=1的Tensordot: > > > np。Tensordot (a, b, axes=1) 数组([16,6,8]) 不要使用numpy。如果你有一个复数矩阵,因为矩阵将被平坦化为一个一维数组,那么它将尝试在你的平坦矩阵和向量之间找到复共轭点积(这将失败,因为大小不匹配n*m vs n)。

其他回答

简单的解决方案

使用numpy。点或a.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])

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

注意,虽然可以使用numpy。矩阵(从2021年初开始),其中*将被视为标准矩阵乘法,numpy。矩阵已弃用,可能会在未来的版本中删除。见其文件中的说明(下文转载):

不再推荐使用这个类,即使是线性代数。相反,请使用常规数组。该类将来可能会被删除。

谢谢@HopeKing。


其他的解决方案

也要知道还有其他选择:

As noted below, if using python3.5+ and numpy v1.10+, 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 answer and 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.dot with two major exceptions: no scalar multiplication but it works with stacks of matrices. >>> np.matmul(a, b) array([16, 6, 8]) numpy.inner functions the same way as numpy.dot for matrix-vector multiplication but behaves differently for matrix-matrix and tensor multiplication (see Wikipedia regarding the differences between the inner product and dot product in general or see this SO answer regarding 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]]) If you have multiple 2D arrays to dot together, you may consider the np.linalg.multi_dot function, which simplifies the syntax of many nested np.dots. Note that this only works with 2D arrays (i.e. not for matrix-vector multiplication). >>> 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]])


边缘情况的罕见选项

如果有张量(维数大于或等于1的数组),可以使用numpy。带有可选参数axes=1的Tensordot: > > > np。Tensordot (a, b, axes=1) 数组([16,6,8]) 不要使用numpy。如果你有一个复数矩阵,因为矩阵将被平坦化为一个一维数组,那么它将尝试在你的平坦矩阵和向量之间找到复共轭点积(这将失败,因为大小不匹配n*m vs n)。