ValueError: shape mismatch: with same shape

ValueError: shape mismatch: with same shape

我遇到了一个我不太理解的奇怪输出的基本错误:

复制步骤

arr1 = np.zeros([6,10,50])
arr2 = np.zeros([6,10])
arr1[:, :, range(25,26,1)] = [arr2]

产生这个错误:

ValueError: shape mismatch: value array of shape (1,6,10) could not be broadcast to indexing result of shape (1,6,10)

谁能解释一下我做错了什么?

arr2 添加一个额外的维度:

arr1[:, :, range(25,26,1)] = arr2.reshape(arr2.shape + (1,))

此处使用的 range 更简单的表示法:

arr1[:, :, 25:26)] = arr2.reshape(arr2.shape + (1,))

(和 slice(25,26,1)slice(25,26) 也可以工作;只是为了增加选项和可能的混淆。)

或者在arr2的末尾插入一个额外的轴:

arr1[..., 25:26] = arr2[..., np.newaxis]

(其中 ... 表示 "as many dimensions as possible")。您也可以使用 None 而不是 np.newaxis;后者可能更明确,但任何了解 NumPy 的人都会将 None 视为插入额外的维度(轴)。

当然你也可以一开始就把arr2设为3维:

arr2 = np.zeros([6,10,1])

请注意,从左侧使用时广播 确实有效:

>>> arr1 = np.zeros([50,6,10])   # Swapped ("rolled") dimensions
>>> arr2 = np.zeros([6,10])
>>> arr1[25:26, :, :] = arr2     # No need to add an extra axis

只是像你的代码一样,从右边使用时它不起作用。

由于 range(25, 26, 1) 实际上是一个数字,您可以使用:

arr1[:, :, 25:26] = arr2[..., None]

或:

arr1[:, :, 25] = arr2

代替arr1[:, :, range(25,26,1)] = [arr2]

请注意,对于未缩减为单个数字的 ranges/slices,第一行将使用 broadcasting

您的原始代码不起作用的原因是您以不兼容的方式混合了 NumPy 数组和 Python list,因为 NumPy 将 [arr2] 解释为具有形状(1, 6, 10) 而结果预期的形状是 (6, 10, 1) (您得到的错误基本上与此有关。)


上述解决方案旨在确保 arr2 处于兼容状态。 另一种可能性是改变收件人的形状,这将允许您分配 [arr2],例如:

arr1 = np.zeros([50,6,10])
arr2 = np.zeros([6,10])
arr1[25:26, :, :] = [arr2]

虽然这种方法可能效率较低,因为 arr2[..., None] 只是 arr2 中相同数据的内存视图,而 [arr2] 正在创建(阅读:为) 一个新的 list 对象,这需要一些转换(发生在引擎盖下)分配给 NumPy 数组。