也许一点解释和直觉可能会帮助未来的读者更好地理解切片。
我(无耻地)使用Stuart Berg's solution 向用户解释切片以获得直观的感觉。
数组和掩码定义:
In [57]: a_3d # array with unique numbers for better understanding.
Out[57]:
array([[[13, 14, 15],
[23, 24, 25],
[33, 34, 35]],
[[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]],
[[ 0, 1, 2],
[30, 31, 32],
[40, 41, 42]]], dtype=uint8)
将上述 3D 数组理解为 3x3 数组的三个切片,最顶部的数组具有索引 0,中心一个具有索引 1,底部一个具有索引 2。
布尔掩码:
In [58]: a_2d_index
Out[58]:
array([[False, False, True],
[False, False, False],
[False, True, True]], dtype=bool)
现在,让我们使用布尔掩码 a_2d_index 对数组 a_3d 进行切片
In [68]: a_3d[:, a_2d_index] # : means apply the mask to all the slices(here 3)
Out[68]:
array([[15, 34, 35],
[ 5, 10, 11],
[ 2, 41, 42]], dtype=uint8)
好的,现在我们得到了上面的结果。为什么以及如何?所以,想象一下:我们获取布尔掩码数组,然后将数组 a_3d 叠加在它的每个切片上。
现在,无论掩码中有布尔值True,数组a_3d 中的相应元素将(发光?)并为结果数组做出贡献。当我们将掩码放在每个切片上时,每个切片都会发生这种情况(因为我们使用了:,所以我们对数组a_3d 中的所有切片都这样做)。
好了,切片完成了!现在,我们要分配新值(其中掩码具有布尔值 True)。
分配新值:
In [69]: a_1d_fill
Out[69]: array([10, 20, 30])
这是我们拥有的一维数组。但是,掩码是二维数组。因此,我们使用 np.newaxis 将其更改为 2D
In [70]: a_2d_fill = a_1d_fill[:, np.newaxis]
In [71]: a_2d_fill
Out[71]:
array([[10],
[20],
[30]])
In [73]: a_3d[:, a_2d_index] = a_2d_fill
现在,此分配会将值 10 复制到布尔掩码具有 True 值的第一个切片中的索引,然后将值 20 复制到布尔掩码具有值 True 的第二个切片中的索引最后将值 30 复制到布尔掩码值为 True 的第三个切片中的索引。
最后的结果是这样的:
In [74]: a_3d
Out[74]:
array([[[13, 14, 10],
[23, 24, 25],
[33, 10, 10]],
[[ 3, 4, 20],
[ 6, 7, 8],
[ 9, 20, 20]],
[[ 0, 1, 30],
[30, 31, 32],
[40, 30, 30]]], dtype=uint8)
呸!那真的很长。因此,简而言之,结果数组在第一、第二和第三个切片中应分别具有值 10、20 和 30(其中布尔掩码的值为 True)。
P.S.:切片提供原始数组的 views 或 references。因此,当我们使用切片更改值时,这将影响原始数组。因此,这是一个就地修改。