使用两个布尔数组索引 2D np.array 时的意外行为

Posted

技术标签:

【中文标题】使用两个布尔数组索引 2D np.array 时的意外行为【英文标题】:Unexpected behaviour when indexing a 2D np.array with two boolean arrays 【发布时间】:2016-04-24 22:58:29 【问题描述】:
two_d = np.array([[ 0,  1,  2,  3,  4],
                  [ 5,  6,  7,  8,  9],
                  [10, 11, 12, 13, 14],
                  [15, 16, 17, 18, 19],
                  [20, 21, 22, 23, 24]])

first = np.array((True, True, False, False, False))
second = np.array((False, False, False, True, True))

现在,当我进入时:

two_d[first, second]

我明白了:

array([3,9])

这对我来说没有多大意义。谁能简单解释一下?

【问题讨论】:

【参考方案1】:

检查documentation on boolean indexing。

two_d[first, second]two_d[first.nonzero(), second.nonzero()] 相同,其中:

>>> first.nonzero()
(array([0, 1]),)
>>> second.nonzero()
(array([3, 4]),)

用作索引,这将选择 3 和 9,因为

>>> two_d[0,3]
3
>>> two_d[1,4]
9

>>> two_d[[0,1],[3,4]]
array([3, 9])

也与轻度相关:NumPy indexing using List?

【讨论】:

【参考方案2】:

当给定多个布尔数组作为索引时,NumPy 将 True 值的索引配对。 first 中的第一个真值与second 中的第一个真值配对,以此类推。 NumPy 然后获取每个 (x, y) 索引处的元素。

这意味着two_d[first, second] 等价于:

two_d[[0, 1], [3, 4]]

换句话说,您正在检索索引 (0, 3) 和索引 (1, 4) 处的值; 39。请注意,如果两个数组具有不同数量的真值,则会引发错误!

documents on advanced indexing 简要提及此行为并建议将np.ix_ 作为“不那么令人惊讶”的替代方案:

使用obj.nonzero() 类比可以最好地理解组合多个布尔索引数组或布尔值与整数索引数组。 ix_ 函数也支持布尔数组,并且可以毫无意外地工作。

因此您可能正在寻找:

>>> two_d[np.ix_(first, second)]
array([[3, 4],
       [8, 9]])

【讨论】:

要得到我认为你想要得到的,你可以使用 two_d[first].T[second].T @pixelbrei:是的,这可以在这里工作,尽管文档建议使用 np.ix_ 来获得所需的结果。

以上是关于使用两个布尔数组索引 2D np.array 时的意外行为的主要内容,如果未能解决你的问题,请参考以下文章

用布尔数组索引 SciPy 稀疏矩阵

使用索引同时从 numpy 2D 数组的行中减去多个值

python中列表子集的布尔索引

查找值为真的布尔数组的索引

比较两个以上的numpy数组

在 numpy 中从具有索引的 2D 矩阵构建 3D 布尔矩阵