Python numpy ValueError: 操作数不能与形状一起广播

在 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)纠正了这个问题,但是原来的问题仍然存在。

962944 次浏览

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

(请注意,如果 Xy属于 numpy.matrix类型,则可以使用星号作为矩阵乘法。我的建议是远离 numpy.matrix,它往往比简化事情更复杂。)

您的数组在使用 numpy.dot时应该没有问题; 如果在 numpy.dot上出现错误,那么肯定还有其他错误。如果 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)

每间 笨手笨脚的医生:

在操作两个数组时,NumPy 按元素比较它们的形状。它从后面的维度开始,然后向前推进。在下列情况下,两个维度是兼容的:

  • 他们是平等的,或者
  • 其中一个是1

换句话说,如果你试图乘以两个矩阵(在线性代数意义上) ,那么你想要 X.dot(y),但如果你试图广播标量从矩阵 yX,那么你需要执行 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]])

有可能错误不是发生在点乘上,而是发生在。 例如,试试这个

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.mat(x) * np.mat(y)就行了。

您正在寻找 np.matmul(X, y)。在 Python 3.5 + 中,您可以使用 X @ y

我们可能会混淆自己,认为 a * b 是一个点乘。

但事实上,它是广播。

网点产品: 点(b)

广播:

广播这个术语指的是 numpy 如何使用不同的 在算术运算过程中导致某些 约束,则较小的数组在较大的数组中广播,以便 它们有相容的形状。

(m,n) +-/* (1,n)→(m,n) : 运算将应用于 m 行

将数组转换为矩阵,然后执行乘法运算。

X = np.matrix(X)


y = np.matrix(y)


X*y
ValueError: operands could not be broadcast together with shapes (x ,y) (a ,b)

其中 x,y 是变量

基本上,当 y (no。)不等于另一个多维数组中的元素数。

现在让我们通过 ex = > 分开编码

import numpy as np
arr1= np.arange(12).reshape(3,

Arr1输出

array([[ 0,  1,  2,  3],
[ 4,  5,  6,  7],
[ 8,  9, 10, 11]])




arr2= np.arange(4).reshape(1,4)

或者(两者都是相同的1行和4列)

arr2= np.arange(4)

Arr2 = > 的输出

array([0, 1, 2, 3])
 

No of element in arr2等于 no of the column in arr1它将被执行。

    for x,y in np.nditer([a,b]):
print(x,y)
    

输出 = >

0 0
1 1
2 2
3 3
4 0
5 1
6 2
7 3
8 0
9 1
10 2
11 3

关于广播,我们应该考虑两点。 第一: 什么是可能的。 第二: 有多少可能的事情是由 numpy 完成的。

我知道这可能看起来有点混乱,但我会通过一些例子来说明。

让我们从零开始。

假设我们有两个矩阵,第一个矩阵有三个维度(A) ,第二个矩阵有五个维度(B)。 Numpy 尝试匹配最后/尾随尺寸。所以 numpy 不关心 B 的前两个尺寸。 然后 numpy 比较这些尾随的维度。当且仅当它们相等或者其中一个为1时,numpy 说“ OK,你们两个匹配”。如果这些条件不能满足,麻木会说“对不起... 这不是我的工作!”.

但是我知道你可能会说,比较最好是在可以设计的时候进行(4,2/9,3)。你可以说它可以被一个整数复制/广播(例子中的2/3)。我同意你的看法。这就是为什么我在开始讨论的时候区分了什么是可能的,什么是麻木的能力。

这是因为 X 和 y 不是相同的类型。例如 X 是一个 numpy 矩阵,y 是一个 numpy 数组!

错误: 操作数不能与形状(2,3)(2,3,3)一起广播

当两个数组的形状不相同时,就会发生这种错误。

为了纠正这一点,您需要重新设置一个数组的形状以匹配另一个数组。

看下面的例子

a1 = array([1, 2, 3])shape = (2,3)

a3 =array([[[1., 2., 3.],
[2., 3., 2.],
[2., 4., 5.]],


[[1., 0., 3.],
[2., 3., 7.],
[2., 4., 6.]]])

with shape = (2,3,3)

如果我尝试运行 np.multiply(a2,a3),它将返回下面的错误

错误: 操作数不能与形状(2,3)(2,3,3)一起广播

要解决这个问题,看看广播规则

which state hat Two dimensions are compatible when:
#1.they are equal, or
#2.one of them is 1`


因此,让我们重塑 a2。

reshaped = a2.reshape(2,3,1)

现在试着运行 np.multiply(reshaped,a3)

乘法将运行成功! !