问题描述
当我将NxN numpy矩阵乘以N个元素的numpy数组时,出现错误,提示形状未对齐。
from numpy import matrix,ones,eye
A = matrix(eye(3))
b = ones(3)
A*b
ValueError: shapes (3,3) and (1,3) not aligned: 3 (dim 1) != 1 (dim 0)
同时放置向量不能解决问题。
A*b.T
ValueError: shapes (3,3) and (1,3) not aligned: 3 (dim 1) != 1 (dim 0)
这很有意义,因为numpy无法区分列向量和行向量,因此bT等于b。
如何执行简单的矩阵矢量乘法?
1楼
(不要使用np.matrix
,它 。而是仅对线性代数使用2D数组。)
使用矩阵乘法运算符@
:
In [177]: from numpy import ones,eye
...: A = eye(3)
...: b = ones(3)
...: A @ b
Out[177]: array([1., 1., 1.])
2楼
问题来自于这样一个事实,即运算符“ *”正在按元素执行逐元素乘法而不是矩阵乘法。 在python 3中,可以使用wm建议的'@'运算符来完成此操作。 但是,在python 2中,必须使用。
import numpy as np
result = np.dot(A,b)
“ *”运算符将尝试将A的每个元素与b的对应元素相乘。 如果这些形状不同,则会看到错误。
编辑:我误解了OP的问题。 如果两个对象都是矩阵,则'*'将用于矩阵乘法。 但是,np.ones(3)会生成一个numpy数组,它不是numpy矩阵对象,因此它不起作用,并尝试进行逐元素乘法。
如果b变为:
b = np.matrix((1,1,1)).T
然后代码将起作用。 还应注意,即使A和b都是矩阵对象,numpy数组或两者的混合,np.dot(A,b)仍将起作用,使其成为最通用的解决方案。
3楼
因为A
是矩阵,Python调用A
的__mul__
方法以b
为参数计算A*b
。
也就是说,它称为A.__mul__(b)
。
numpy matrix
坚持将所有内容都设为2-d矩阵,因此它将b
转换为matrix
然后再执行矩阵乘法。
将b
转换为numpy矩阵时,结果的形状为(1, 3)
:
In [248]: b
Out[248]: array([1., 1., 1.])
In [249]: np.matrix(b).shape
Out[249]: (1, 3)
然后__mul__
抱怨形状未对齐,因为A
具有形状(3, 3)
,而转换后的b
具有形状(1, 3)
。
解决此问题的一种方法是,在进行乘法运算之前,确保b
为具有形状(3, 1)
2-d:
In [250]: b = ones((3, 1))
In [251]: A * b
Out[251]:
matrix([[1.],
[1.],
[1.]])
但是从长远来看,最好将代码修改为完全不使用matrix
,如@wm所述。