提问人:Locutus 提问时间:8/13/2023 最后编辑:SidLocutus 更新时间:8/13/2023 访问量:49
在 NumPy ndarray 中混合基本索引和高级索引获得的数组形状
Shapes of arrays obtained by mixed basic and advanced indexing in NumPy ndarray
问:
代码如下:
import numpy as np
x = np.arange(2*32*32*8*16)
x = x.reshape(2, 32, 32, 8, 16)
print("x-shape=", x.shape)
y = x[0, 3:5, 8:10, [1, 2, 3, 4, 5], :]
z = x[0][3:5, 8:10, [1, 2, 3, 4, 5], :]
print("y-shape=", y.shape)
print("z-shape=", z.shape)
和输出:
x-shape= (2, 32, 32, 8, 16)
y-shape= (5, 2, 2, 16)
z-shape= (2, 2, 5, 16)
我希望数组 y 和 z 的形状相等,但事实并非如此。我需要的实际上是 z 的形状。
有人可以解释或指出我的标准吗?
谢谢!
答:
请参阅有关索引的 numpy 文档:
单元素索引的工作方式与其他标准 Python 序列的工作方式完全相同。它从 0 开始,接受从数组末尾开始索引的负索引。[...]请注意,如果索引数少于维度的多维数组编制索引,则会得到一个子维数组。
从而得到 的第一个多维子数组。 将有形状.然后,再次对此进行切片,使用多维切片,切片数量与维度一样多。您将获得一个相同维度的数组,其中所有维度都已切片:将前 32 个投影为 2 (5 - 3),将第二个 32 投影为 2 以及 (10 - 8),将 8 投影到 5(选择索引 1 - 5),并将 16 保留为 16 ()。你得到.x[0]
x
x[0]
(32, 32, 8, 16)
[3:5, 8:10, [1, 2, 3, 4, 5], :]
:
(2, 2, 5, 16)
这里可能让您感到困惑的是,高级索引规则(更糟糕的是,您结合了高级索引和基本索引)适用,因为您的一个切片是 .因此,numpy 不会创建一个视图,而是一个副本。如果改用正确的切片,则高级索引将不适用,并且将按预期进行。[1, 2, 3, 4, 5]
1:6
y.shape
(2, 2, 5, 16)
这样做的原因是视图(“胖指针”)和高级索引之间存在根本区别:使用高级索引时,您不必使用具有恒定差异的连续范围(算术级数)。您可以使用质数,您最喜欢的数字,无论用于索引。因此,由指针和形状组成的简单视图(它告诉您在每个方向上移动一个指针时如何移动指针,以及数组的结束位置)是不够的。 实际上需要浏览您的索引列表并选择您想要的索引,创建一个新数组。numpy
评论
y
您的阵列:
In [24]: x.shape
Out[24]: (2, 32, 32, 8, 16)
In [25]: y=x[0,:,:,:,[1,2,3,4,5]]
In [26]: y.shape
Out[26]: (5, 32, 32, 8)
让我们尝试不使用首字母 0,即没有“中间”切片:y
In [27]: z=x[:,:,:,:,[1,2,3,4,5]]
In [28]: z.shape
Out[28]: (2, 32, 32, 8, 5)
y
是一个副本,它自己的“基础”:
In [29]: y.base
但是是另一个数组的转置。请注意,维度是第一位的:z
5
In [30]: z.base.shape
Out[30]: (5, 2, 32, 32, 8)
高级索引生成副本,然后转置以按正确的顺序获取索引这一事实没有记录。但我怀疑这是意想不到的混合基本/高级形状的关键。
我们也在大步前进中看到了这一点:
In [34]: x.strides
Out[34]: (1048576, 32768, 1024, 128, 8)
In [35]: y.strides
Out[35]: (65536, 2048, 64, 8)
In [36]: z.base.strides
Out[36]: (131072, 65536, 2048, 64, 8)
In [37]: z.strides
Out[37]: (65536, 2048, 64, 8, 131072)
初始索引为 ,混合文档所谈论的并不明显。如果我们尝试从中选择“对角线”,则更是如此。尺寸 2 维度应该是第一个还是最后一个?0
ambiguity
x
In [54]: z = x[[1,0],:,:,:,[1,2]]
In [55]: z.shape
Out[55]: (2, 32, 32, 8)
评论
y
混合了基本(切片)和高级索引,切片位于中间。高级维度 5 放在首位。这很尴尬,但有记录(偶尔会出现在 SO 上)。