如果我跑步:
x = np.zeros(6)
y = np.zeros([7, 6])
z = y * x
然后一切都很好,并且没有Python错误。
但是,我正在使用一个包含一个函数(如果bar调用)的Python模块(如果foo调用),该模块返回一个7x6的NumPy数组。它具有与上述y
相同的形状,并且具有相同的数据类型(float64)。但是当我运行以下命令时:
x = np.zeros(6)
y = foo.bar()
z = y * x
我收到以下错误:
ValueError: shapes (7,6) and (1,6) not aligned: 6 (dim 1) != 1 (dim 0)
但是据我所知,y
在这两个示例中是完全相同的格式,具有相同的形状和数据类型。是什么导致此错误,为什么在第一个示例中没有导致此错误?
答案 0 :(得分:1)
我不知道您正在运行哪个版本,但是我正在Python 3上运行1.16.3版本。
在我看来,您对x
的定义与示例代码段中的定义不同。您似乎将其定义为6x1矩阵,而不是“矢量”,在Numpy上它被认为只有一维。尝试将y
乘以np.zeros([6,1])
,您会看到错误。
底线是:
.shape
属性,这在进行矩阵乘法时非常有用。答案 1 :(得分:1)
In [446]: x = np.zeros(6)
...: y = np.zeros([7, 6])
...: z = y * x
In [447]: z.shape
Out[447]: (7, 6)
在这里,我们正在进行元素级乘法,即(7,6)与(6,)。通过广播(6,)变为(1,6),然后变为(7,6)以匹配y
。
显然在foo.bar
情况下,y
是np.matrix
子类:
In [454]: y1 = np.matrix(y)
In [455]: y1*x
---...
219 # This promotes 1-D vectors to row vectors
--> 220 return N.dot(self, asmatrix(other))
...
ValueError: shapes (7,6) and (1,6) not aligned: 6 (dim 1) != 1 (dim 0)
请注意y1
的不同显示:
In [456]: y1
Out[456]:
matrix([[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.]])
将np.matrix
中的*
定义为np.dot
,即矩阵乘积。 x
也将转换为np.matrix
,从而生成(1,6)矩阵。该错误消息来自矩阵乘法的定义。
np.multiply
可以用于强制逐元素乘法。注意结果的类别:
In [458]: np.multiply(y1,x)
Out[458]:
matrix([[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.]])
不鼓励像这样的np.matrix
这样的混乱。