📜  如何修复:ValueError:操作数无法与形状一起广播?

📅  最后修改于: 2022-05-13 01:55:41.408000             🧑  作者: Mango

如何修复:ValueError:操作数无法与形状一起广播?

广播是指 NumPy 的能力 在算术运算期间处理不同形状的数组。实际上,在数组中,可以对数组的对应元素进行算术运算。

  • 如果两个数组的形状相同,那么两个数组之间的算术运算就可以顺利完成。
  • 如果2 个数组具有不同的形状,则无法进行元素到元素的操作。但是NumPy使用广播的概念使其成为可能。较小的数组被广播到较大数组的大小,以便对它们执行算术运算。

例子:

在这里,一个大小为 1×1 的较小数组被广播到一个更大的数组大小为 2×1,其中第 2 行也包含第 1的相同元素,即 1。所以第 1 行=> 1+1=2 & 2nd行 => 2+1=3。

如果我们尝试执行 有时 NumPy 广播失败的 2 个不同形状或不同维度的数组之间的算术运算。它会引发错误,例如操作数无法与形状一起广播。在某些情况下,广播可能会发生并且会失败。所以如果它失败了,我们需要转换数组的形状。

示例:显示广播失败的位置

Python3
# import necessary packages
import numpy as np
  
# create 2 arrays
Array1 = np.arange(2).reshape(1, 2)
Array2 = np.arange(2, 10).reshape(3, 3)
  
# print 2 arrays
print(Array1)
print(Array2)
  
print(Array1+Array2)


Python3
# import necessary packages
import numpy as np
  
# create 2 arrays
Array1 = np.arange(4).reshape(2, 2)
Array2 = np.arange(4, 8).reshape(2, 2)
  
# print 2 arrays
print(Array1)
print(Array2)
  
# addition between 2 arrays
print('--Addition--')
print(Array1+Array2)


Python3
# import necessary packages
import numpy as np
  
# create 2 arrays
Array1 = np.arange(2).reshape(1, 2)
Array2 = np.arange(2, 8).reshape(3, 2)
  
# print 2 arrays
print(Array1)
print(Array2)
  
# addition between 2 arrays
print('--Addition--')
print(Array1+Array2)


Python3
# import necessary packages
import numpy as np
  
# create 2 arrays
Array1 = np.arange(4).reshape(2, 2)
Array2 = np.arange(2).reshape(2, 1)
  
# print 2 arrays
print(Array1)
print(Array2)
  
# subtraction between 2 arrays
print('--Subtraction--')
print(Array1-Array2)


Python3
# import necessary packages
import numpy as np
  
# create 2 arrays
Array1 = np.arange(2).reshape(2, 1)
Array2 = np.arange(2).reshape(1, 2)
  
# print 2 arrays
print(Array1)
print(Array2)
  
# addition between 2 arrays
print('--Addition--')
print(Array1+Array2)


Python3
# import necessary packages
import numpy as np
  
# create 2 arrays
Array1 = np.arange(1).reshape(1, 1)
Array2 = np.arange(2).reshape(1, 2)
  
# print 2 arrays
print(Array1)
print(Array2)
  
# addition between 2 arrays
print('--Addition--')
print(Array1+Array2)


输出:

抛出的错误

为了执行广播,它在内部遵循一些规则将小型数组转换为大型数组的形状。因此,每当抛出错误时,请检查下面提到的规则以修改数组的大小以成功广播。

广播规则

规则1:

如果两个数组具有相同的形状或尺寸,则解释器不会引发错误。可以对相应的元素执行算术运算。

示例:描述规则 1

Python3

# import necessary packages
import numpy as np
  
# create 2 arrays
Array1 = np.arange(4).reshape(2, 2)
Array2 = np.arange(4, 8).reshape(2, 2)
  
# print 2 arrays
print(Array1)
print(Array2)
  
# addition between 2 arrays
print('--Addition--')
print(Array1+Array2)

输出:

解释

规则 2:

如果一个数组的一个维度为 1,则需要将相邻维度与另一个数组进行比较。如果它们相同,它会在它们之间广播并执行算术运算。

示例:描述规则 2

Python3

# import necessary packages
import numpy as np
  
# create 2 arrays
Array1 = np.arange(2).reshape(1, 2)
Array2 = np.arange(2, 8).reshape(3, 2)
  
# print 2 arrays
print(Array1)
print(Array2)
  
# addition between 2 arrays
print('--Addition--')
print(Array1+Array2)

输出:

这里Array1的一维值为1,所以我们需要比较第二维,2个数组的值是否相同。如果相同,则广播发生,否则失败。我们需要按照规则转换数组的大小。在这个例子中,值是相同的,所以加法运算可以顺利执行。

这里 Array1 被转换为一个 3×2 形状的数组,该数组被添加到 Array 2 以给出结果。

示例:描述规则 2

Python3

# import necessary packages
import numpy as np
  
# create 2 arrays
Array1 = np.arange(4).reshape(2, 2)
Array2 = np.arange(2).reshape(2, 1)
  
# print 2 arrays
print(Array1)
print(Array2)
  
# subtraction between 2 arrays
print('--Subtraction--')
print(Array1-Array2)

输出:

规则 3:

如果数组形状m x nn x m 。在这种情况下,如果 m>n则将两个数组广播到 m x m 中,否则如果 n>m 则将n x n 广播。

示例:描述规则 3

Python3

# import necessary packages
import numpy as np
  
# create 2 arrays
Array1 = np.arange(2).reshape(2, 1)
Array2 = np.arange(2).reshape(1, 2)
  
# print 2 arrays
print(Array1)
print(Array2)
  
# addition between 2 arrays
print('--Addition--')
print(Array1+Array2)

输出:

解释

规则 4:

如果任何阵列的形状为1 x 1 ,那么无论其他阵列形状如何,它都会简单地将形状为 1 x 1的阵列广播到另一个阵列的形状。

示例:描述规则 4

Python3

# import necessary packages
import numpy as np
  
# create 2 arrays
Array1 = np.arange(1).reshape(1, 1)
Array2 = np.arange(2).reshape(1, 2)
  
# print 2 arrays
print(Array1)
print(Array2)
  
# addition between 2 arrays
print('--Addition--')
print(Array1+Array2)

输出

Array1 的形状为 1 x 1 ,因此它被广播到Array2 的形状,即1 x 2

上述广播失败的例子的解决方案是简单地将Array1 的形状转换为 1 x 3Array2 的形状根据场景 2 转换为 3 x 2