这与 python 的切片语法有关。本质上,obj[a:b:c] 是obj.__getitem__(slice(a,b,c)) 的语法简写。
x[:] 只返回x 的“完整切片” - 也就是说,它返回x 的精确副本。做x[:][:][1] 和做x[1] 没什么区别。
同时,x[:,:,1] 等同于:
x.__getitem__((slice(), slice(), 1))
即使用三元组作为索引。对于普通的 python list,这会失败,但 Numpy 会优雅地接受它。要了解 Numpy 是如何做到的,让我们仔细看看这个例子:
>>> x = np.array([[[1,2],[5,6]],[[9,7],[12,23]]])
>>> x[1]
array([[ 9, 7],
[12, 23]])
>>> x[:,1]
array([[ 5, 6],
[12, 23]])
>>> x[:,:,1]
array([[ 2, 6],
[ 7, 23]])
>>> x[:,:,:,1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: too many indices for array: array is 3-dimensional, but 4 were indexed
我们可以看到一个模式。
当你给一个 Numpy 数组一个元组作为索引时,它会将元组的每个元素映射到一个维度,然后将元组的后续元素应用于每个维度。简而言之:
-
x[1] 只是从数组的第一维获取索引 1 处的元素。这是单个元素[[9, 7], [12, 23]]
-
x[:, 1] 从数组第一个维度中的 每个元素 获取索引 1 处的元素。也就是说,它从数组的 第二维 中获取索引 1 处的元素。这是两个元素:[5, 6] 和 [12, 23]。 Numpy 将它们组合在一个列表中。
-
x[:, :, 1] 遵循相同的模式 - 它从数组的 第三维 获取索引 1 处的元素。这次有四个唯一元素:2 和 6 来自第二维中的第一个元素,7 和 23 来自第二维中的第二个元素。 Numpy 在嵌套列表中按维度对它们进行分组。
-
x[:, :, :, 1] 失败,因为数组只有三个维度 - 无法进一步细分任何第三个维度的元素。