ValueError:形状不匹配:具有相同形状

时间:2019-10-29 10:35:52

标签: python numpy shapes numpy-ndarray numpy-slicing

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

复制步骤

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)

谁能解释我在做什么错?

2 个答案:

答案 0 :(得分:1)

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]

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

就像从代码中那样,从右边使用它只是行不通。

答案 1 :(得分:1)

由于range(25, 26, 1)实际上是一个数字,因此您可以使用以下任一方法:

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

或:

arr1[:, :, 25] = arr2

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

请注意,对于不减少到单个数字的范围/切片,第一行将使用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数组。