python numpy ValueError:操作数无法与形状一起广播
- 2024-11-29 08:41:00
- admin 原创
- 220
问题描述:
在 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)
,但原来的问题仍然存在。
解决方案 1:
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
,则一定是存在其他错误。如果 的形状不正确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)
解决方案 2:
根据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]])
解决方案 3:
您正在寻找np.matmul(X, y)
。在 Python 3.5+ 中,您可以使用X @ y
。
解决方案 4:
错误可能不是发生在点积中,而是发生在点积之后。例如,试试这个
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)
这个错误具有误导性;但是该行确实存在问题。
解决方案 5:
使用np.mat(x) * np.mat(y)
,就会起作用。
解决方案 6:
我们可能会混淆,认为 a * b 是点积。
但事实上,这是广播。
点积:
a.dot(b)
播送:
术语“广播”指的是 numpy 在算术运算期间如何处理具有不同维度的数组,这会导致某些约束,较小的数组会在较大的数组中广播,以便它们具有兼容的形状。
(m,n) +-/* (1,n) → (m,n) :该操作将应用于 m 行
解决方案 7:
将数组转换为矩阵,然后执行乘法。
X = np.matrix(X)
y = np.matrix(y)
X*y
解决方案 8:
我们应该考虑有关广播的两点。第一:什么是可能的。第二:numpy 完成了多少可能的事情。
我知道这看起来可能有点令人困惑,但我会通过一些例子来解释清楚。
让我们从零级开始。
假设我们有两个矩阵。第一个矩阵有三个维度(名为 A),第二个矩阵有五个维度(名为 B)。numpy 尝试匹配最后一个/尾随维度。因此 numpy 不关心 B 的前两个维度。然后 numpy 将这些尾随维度相互比较。并且当且仅当它们相等或其中一个为 1,numpy 才会说“OK,你们两个匹配”。如果这些条件不满足,numpy 会说“抱歉……这不是我的工作!”。
但是我知道您可能会说,当它们可数形参 (4 和 2 / 9 和 3) 时,比较最好以能够处理的方式进行。您可能会说它可以被整数复制/广播 (我们的例子中为 2/3)。我同意您的观点。这就是我在讨论之初区分什么是可能的以及 numpy 的能力是什么的原因。
解决方案 9:
这是因为 X 和 y 不是相同的类型。例如 X 是一个 numpy 矩阵,而 y 是一个 numpy 数组!
解决方案 10:
错误:操作数不能与形状 (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)
乘法将会成功!!
解决方案 11:
ValueError: operands could not be broadcast together with shapes (x ,y) (a ,b)
其中 x ,y 是变量
基本上,当 y 的值(列数)不等于另一个多维数组中的元素数量时,就会发生此错误。
现在让我们通过 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])
arr2 中的元素数与 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
解决方案 12:
虽然这个问题已经很老了,但我还没有在这里看到这个答案,因此发布了它。
主要区别在于数组乘法与矩阵乘法。对于矩阵乘法,您应该使用np.matmul,它具有您请求的输出,即 [n,m] * [m,l] = [n,l]。
请参阅以下示例:
x1 = np.arange(12.0).reshape((4, 3))
x2 = np.arange(3).reshape((3))
x1
array([[ 0., 1., 2.],
[ 3., 4., 5.],
[ 6., 7., 8.],
[ 9., 10., 11.]])
x2
array([0, 1, 2])
x1 * x2
array([[ 0., 1., 4.],
[ 0., 4., 10.],
[ 0., 7., 16.],
[ 0., 10., 22.]])
np.multiply(x1, x2)
array([[ 0., 1., 4.],
[ 0., 4., 10.],
[ 0., 7., 16.],
[ 0., 10., 22.]])
np.matmul(x1, x2)
array([ 5., 14., 23., 32.])