Numpy 2-D数组布尔蒙版

时间:2018-08-26 00:57:46

标签: arrays numpy indexing

我不了解此numpy tutorial中的一个示例。

a = np.arange(12).reshape(3,4)
b1 = np.array([False, True, True])
b2 = np.array([True, False, True, False])

那为什么a[b1,b2]返回array([4, 10])?它不应该返回array([[4, 6], [8, 10]])吗?

任何详细的解释都值得赞赏!

3 个答案:

答案 0 :(得分:1)

当您对具有多个数组的数组进行索引时,它会使用索引数组中的成对元素进行索引

>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> b1
array([False,  True,  True], dtype=bool)
>>> b2
array([ True, False,  True, False], dtype=bool)
>>> a[b1, b2]
array([ 4, 10])

请注意,这等效于:

>>> a[(1, 2), (0, 2)]
array([ 4, 10])

a[1, 0]a[2, 2]的元素

>>> a[1, 0]
4
>>> a[2, 2]
10

由于这种成对行为,通常不能使用单独的长度数组来索引(它们必须能够广播)。因此,此示例有点意外,因为两个索引数组都有两个索引,它们分别为True;例如,如果一个具有三个True值,则会得到一个错误:

>>> b3 = np.array([True, True, True, False])
>>> a[b1, b3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (3,)

因此,这特别是让您知道索引数组必须能够一起广播(这样它才能以一种灵巧的方式将索引分片在一起;例如,如果一个索引数组只有一个值,则将重复该操作)以及其他索引数组中的每个值)。

要获得您期望的结果,您可以分别为结果建立索引:

>>> a[b1][:, b2]
array([[ 4,  6],
       [ 8, 10]])

否则,您也可以将索引数组转换为与a形状相同的2D数组,但是请注意,如果这样做,结果将是线性数组(因为可以提取任意数量的元素出来,当然可能不是正方形):

>>> a[np.outer(b1, b2)]
array([ 4,  6,  8, 10])

答案 1 :(得分:0)

第一个数组的true索引为

>>> i = np.where(b1)
>>> i 
array([1,2])

对于第二个数组,它们是

>>> j = np.where(b2)
>>> j
array([0,1])

一起使用这些索引掩码,

>>> a[i,j]
array([4, 10])

答案 2 :(得分:0)

在2D numpy数组上应用 general 布尔2D蒙版的另一种方法是:

使用矩阵逐元素乘法:

import numpy as np

n = 100
mask = np.identity(n)
data = np.random.rand(n,n)

data_masked = data * mask

在此随机示例中,您仅将元素保留在对角线上。 遮罩可以是任何n×n矩阵。