我不了解此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]])
吗?
任何详细的解释都值得赞赏!
答案 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矩阵。