Python 为什么标注顺序会随着布尔索引而改变?

Python 为什么标注顺序会随着布尔索引而改变?,python,arrays,numpy,indexing,boolean,Python,Arrays,Numpy,Indexing,Boolean,当我们有形状(a,b,c)的M,以及我们用来索引最后一个数组的索引数组v,为什么M[i,:,v]会产生形状(d,b)(其中d是v中的真值的数量)?如下图所示: In [409]: M = zeros((100, 20, 40)) In [410]: val = ones(shape=(40,), dtype="bool") In [411]: M[0, :, :].shape Out[411]: (20, 40) # As expected In [412]: M[0, :, val].

当我们有形状
(a,b,c)
M
,以及我们用来索引最后一个数组的索引数组
v
,为什么
M[i,:,v]
会产生形状
(d,b)
(其中
d
v
中的真值的数量)?如下图所示:

In [409]: M = zeros((100, 20, 40))

In [410]: val = ones(shape=(40,), dtype="bool")

In [411]: M[0, :, :].shape
Out[411]: (20, 40)  # As expected

In [412]: M[0, :, val].shape
Out[412]: (40, 20)  # Huh?  Why (40, 20), not (20, 40)?

In [413]: M[:, :, val].shape
Out[413]: (100, 20, 40)  # s expected again

为什么
M[0,:,val]
具有形状
(40,20)
而不是
(20,40)

根据文档的
布尔索引部分

使用obj.nonzero()类比可以最好地理解将多个布尔索引数组或布尔与整数索引数组相结合

现在我们转到关于结合高级和基本索引的部分

这是一种形式:
x[arr1,:,arr2]

在第一种情况下,高级索引操作产生的维度在结果数组中排在第一位,然后是子空间维度

< <代码> 0 和<代码> IDEN/COD>部分产生<代码>(40)选择,而在中间的<代码>:<代码>产生<代码>(20)。将
零件放在最后,得到的尺寸是
(40,20)
。基本上,它这样做是因为在这种索引样式中存在歧义,所以它始终选择将切片部分放在末尾

选择这些值并保持所需形状(或多或少)的一种方法是使用
np.ix
生成索引元组

M[np.ix_([0],np.arange(20),ind)].shape # (1, 20, 40)
您可以使用
np.squese
删除初始
1
维度

“纯索引数组索引”一节末尾说明了
ix
的这种用法

的文档介绍了您的示例,但我还没有弄清楚它的含义。@BiRico Oops,的确如此。更正。@wwii我通读了一遍,但我没有找到一个例子,他们使用最后一个维度而不是第一个维度来建立布尔索引。对。在我的实际用例中,我也在赋值。我看到关于返回的数组何时是副本以及何时是视图都有一些警告,但似乎我在使用
ix_uu
时确实获得了视图。您没有获得视图,但赋值
arr[foo]=b
始终有效。然而,
arr[foo][bar]=b
相当于
tmp=arr[foo];tmp[bar]=b
如果tmp不是arr上的视图,它将不起任何作用。
M[np.ix_([0],np.arange(20),ind)].shape # (1, 20, 40)