二维 Numpy 数组花式索引 + 掩码

2D Numpy Array Fancy Indexing + Masking

我有:

import numpy as np
a = np.array([[ 4, 99,  2],
              [ 3,  4, 99],
              [ 1,  8,  7],
              [ 8,  6,  8]])

为什么是

a[[True, True, False, False], [1,2]]

等于

array([99, 99])

而不是

array([99, 2],
      [4, 99])

因为我使用布尔掩码选择前两行,使用花式索引选择第 2 和第 3 列?特别是自从打电话

a[[True, True, False, False],:][:, [1,2]]

给了我预期的结果。我猜它是某种广播规则,但对我来说并不明显。谢谢!

我认为它的工作原理如下:

In [284]: a
Out[284]: 
array([[ 4, 99,  2],
       [ 3,  4, 99],
       [ 1,  8,  7],
       [ 8,  6,  8]])

In [286]: bo
Out[286]: array([ True,  True, False, False], dtype=bool)

In [287]: boc
Out[287]: array([1, 2])

现在,一旦我们用布尔掩码 bo 索引 a,我们得到:

In [285]: a[bo]
Out[285]: 
array([[ 4, 99,  2],
       [ 3,  4, 99]])

因为 bo 的计算结果为 [1, 1, 0, 0],这将只是 select a 的前两行。

现在,我们应用 boc[1, 2] 与行 select 组合 掩码 bo

In [288]: a[bo, boc]
Out[288]: array([99, 99])

此处,掩码 boc 应用于 已提取的行 。它 select 第一行的第二个元素,第二行的第三个元素产生 [99, 99].

但是,有趣的是,如果您执行以下操作:

In [289]: a[1, [1, 2]]
Out[289]: array([ 4, 99])

在这种情况下,numpy 广播产生索引 [(1,1), (1,2)]

布尔数组或列表的计算结果好像 where 已将其转换为索引数组:

In [285]: a[[True,True,False,False],[1,2]]
Out[285]: array([99, 99])

In [286]: a[np.where([True,True,False,False]),[1,2]]
Out[286]: array([[99, 99]])

In [287]: np.where([True,True,False,False])
Out[287]: (array([0, 1], dtype=int32),)

In [288]: a[[0,1], [1,2]]
Out[288]: array([99, 99])

所以这是选择 a[0,1]a[1,2],'pair-wise' 选择。

该块使用数组(或等效列表)进行索引,这些数组相互广播以生成 (2,2) 数组:

In [289]: a[np.ix_([0,1], [1,2])]
Out[289]: 
array([[99,  2],
       [ 4, 99]])
In [290]: a[[[0],[1]], [1,2]]
Out[290]: 
array([[99,  2],
       [ 4, 99]])

这种情况相当于 2 阶段索引:a[[0,1],:][:,[1,2]]

我使用的是 np 版本 12。布尔索引在最近的版本中发生了一些变化。例如,如果布尔值的长度不正确,它会运行,但会发出警告(这部分是新的)。

In [349]: a[[True,True,False],[1,2]]
/usr/local/bin/ipython3:1: VisibleDeprecationWarning: boolean index did not match indexed array along dimension 0; dimension is 4 but corresponding boolean dimension is 3
  #!/usr/bin/python3
Out[349]: array([99, 99])

第 13 版的更改描述于:

https://docs.scipy.org/doc/numpy-dev/release.html#boolean-indexing-changes