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 数组。
我遇到了一个我不太理解的奇怪输出的基本错误:
复制步骤
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 数组。