0

我收到一个基本错误,输出奇怪,我不太理解:

重现步骤

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)

谁能解释我做错了什么?

4

2 回答 2

1

添加一个额外的维度到arr2

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

在这里使用的更简单的符号range

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

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

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

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

(其中的...意思是“尽可能多的维度”)。您也可以使用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

只是从右侧使用时它不起作用,就像在您的代码中一样。

于 2019-10-29T10:43:08.597 回答
1

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

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

或者:

arr1[:, :, 25] = arr2

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

请注意,对于不减少为单个数字的范围/切片,第一行将使用broadcasting

您的原始代码不起作用的原因是您list以不兼容的方式混合 NumPy 数组和 Python s,因为 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 数组。

于 2019-10-29T10:53:32.123 回答