python numpy 值错误:操作数形状不能广播在一起
在numpy中,我有两个“数组”,X
的形状是(m,n)
,而y
是一个向量,形状是(n,1)
。
我使用了
X*y
但是出现了错误
ValueError: operands could not be broadcast together with shapes (97,2) (2,1)
当(97,2)x(2,1)
显然是一个合法的矩阵运算,应该给我一个(97,1)
的向量。
编辑:
我已经通过使用X.dot(y)
来修正这个问题,但原来的问题仍然存在。
12 个回答
使用 np.mat(x) * np.mat(y)
,这样就可以了。
这个错误可能不是在点积的计算中出现的,而是在之后的步骤中。比如你可以试试这个:
a = np.random.randn(12,1)
b = np.random.randn(1,5)
c = np.random.randn(5,12)
d = np.dot(a,b) * c
np.dot(a,b)
这个计算是没问题的;但是 np.dot(a, b) * c
就明显不对了(12x1 X 1x5 = 12x5
,这和 5x12
不能逐元素相乘)。不过 numpy 会给你一个错误提示:
ValueError: operands could not be broadcast together with shapes (12,1) (1,5)
这个错误提示可能会让人误解;不过在那一行确实存在问题。
你想要使用 np.matmul(X, y)
这个功能。在 Python 3.5 及以上的版本中,你可以用 X @ y
来代替。
根据 NumPy 的文档:
当对两个数组进行操作时,NumPy 会逐个比较它们的形状。它从最后一个维度开始,然后向前比较。两个维度兼容的情况有:
- 它们相等,或者
- 其中一个是 1
换句话说,如果你想要对两个矩阵进行乘法运算(在数学中说的线性代数),你应该使用 X.dot(y)
。但是如果你想把矩阵 y
中的标量(单个数值)广播到 X
上,那你需要用 X * y.T
。
举个例子:
>>> import numpy as np
>>>
>>> X = np.arange(8).reshape(4, 2)
>>> y = np.arange(2).reshape(1, 2) # create a 1x2 matrix
>>> X * y
array([[0,1],
[0,3],
[0,5],
[0,7]])
dot
是用来做矩阵乘法的,而 *
则是做其他的事情。
我们有两个数组:
X
,形状是 (97,2)y
,形状是 (2,1)
在使用 Numpy 数组时,操作
X * y
是逐个元素进行的,但其中一个或两个值可以在一个或多个维度上扩展,以便让它们能够匹配。这种操作叫做广播。维度中,如果大小是 1 或者缺失的,都可以用来进行广播。
在上面的例子中,维度不兼容,因为:
97 2
2 1
这里在第一维度上有冲突的数字(97 和 2)。这就是上面提到的 ValueError 报错的原因。第二维度是可以的,因为数字 1 和其他的没有冲突。
想了解更多关于广播的规则,可以查看这个链接: http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html
(请注意,如果 X
和 y
是 numpy.matrix
类型,那么可以用星号进行矩阵乘法。我的建议是尽量避免使用 numpy.matrix
,因为它往往会让事情变得更复杂。)
你的数组在使用 numpy.dot
时应该没问题;如果在 numpy.dot
上出现错误,那你可能有其他的bug。如果形状不适合 numpy.dot
,你会得到不同的异常:
ValueError: matrices are not aligned
如果你仍然遇到这个错误,请提供一个最小的示例来说明问题。用你那样形状的数组进行乘法是可以成功的:
In [1]: import numpy
In [2]: numpy.dot(numpy.ones([97, 2]), numpy.ones([2, 1])).shape
Out[2]: (97, 1)