布尔屏蔽的花式索引| Python中的Numpy

时间:2019-06-15 12:46:40

标签: python arrays numpy masking matrix-indexing

我在《 Python数据科学手册》中碰到了这段代码,为了便于阅读,在这里对其进行了修改。 对我来说,这很令人困惑,因为它结合了花式索引和遮罩,而且我无法理解其下发生了什么。

import numpy as np
X = np.arange(12).reshape(3,4)
print("---X----\n",X)
row = np.array([0,1,2])
mask = np.array([1, 0, 1, 0], dtype=bool)
print("\n-----row vector after reshaping ----\n",row[:, np.newaxis])
print("\n ---mask  ----\n",mask)
print("\n ----result-----\n",X[row[:, np.newaxis], mask])

以下是输出:

---X----
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

-----row vector after reshaping ----
 [[0]
 [1]
 [2]]

 ---mask  ----
 [ True False  True False]

 ----result-----
 [[ 0  2]
 [ 4  6]
 [ 8 10]]

我了解到

X[row[:,np.newaxis],[1,2,3]]

开始广播是因为第一个参数的形状为(3,1),第二个参数的形状为(3,)。它同时广播(3,3)的参数,然后花式索引选择相应的定位元素,结果大小就是参数的大小(这是花式索引文档所说的)。

但是我之前发布的代码使我感到困惑。根据我的推断,第二个参数(掩码)等于shape(4,)的[1,0,1,0],第一个参数为

[[0],
[1],
[2]
]
形状(3,1)的

。 在这种情况下,这两个论点都应广播给 (3,4),然后拾取元素,得到大小为-(3,4)的结果矩阵。是的,我知道它违背了布尔蒙版概念的目的,但是我们并没有像X [mask]这样做,因为我们在mask为True的情况下获得了各自的值。 在我们的X[row[:, np.newaxis], mask])声明中, 第一个参数是整数数组,第二个参数是布尔数组。布尔数组不是转换为整数以与第一个参数一起播放,还是布尔数组首先对列进行选择,结果是:

[[0 2],
[4,6],
8,10]
]

在此我们应用第一个参数。

1 个答案:

答案 0 :(得分:1)

您在正确的轨道上,布尔值确实已转换为(或至少可以被视为转换为)索引。也许是这种转换的细节使您感到困惑?

这是docs

中的相关位
  

通常,如果索引包含布尔数组,则结果将为   等同于将obj.nonzero()插入相同位置并使用   上述整数数组索引机制。 x [ind_1,   boolean_array,ind_2]等效于x [(ind_1,)+   boolean_array.nonzero()+(ind_2,)]。

现在,我们将其简单地应用于您的示例:

mask.nonzero()
# (array([0, 2]),)

所以

(row[:, None],) + mask.nonzero()
# (array([[0],
#         [1],
#         [2]]), array([0, 2]))

是有效索引。这会广播到3x2,一切都按预期进行。