python numpy 值错误:操作数形状不能广播在一起

213 投票
12 回答
1173792 浏览
提问于 2025-04-18 12:02

在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 个回答

12

使用 np.mat(x) * np.mat(y),这样就可以了。

14

这个错误可能不是在点积的计算中出现的,而是在之后的步骤中。比如你可以试试这个:

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)

这个错误提示可能会让人误解;不过在那一行确实存在问题。

27

你想要使用 np.matmul(X, y) 这个功能。在 Python 3.5 及以上的版本中,你可以用 X @ y 来代替。

43

根据 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]])
138

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

(请注意,如果 Xynumpy.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)

撰写回答