2017-03-17 153 views
0

我:2D numpy的数组索引花式+屏蔽

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]) 

因为我选择使用布尔掩码和使用花式索引的第二和第三列的前两行?特别是因为打电话

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

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

+0

我得到一个'IndexError:形状不匹配:索引阵列不能与形状(4)一起广播(2,)'对于您的查询... –

+0

这只是下标索引,从每个dim的每个索引中选取一组索引中的每个元素。所以,它的索引用'(0,1)'[0从布尔数组的第一个TRUE elem,1从int索引数组的第一个元素]为第一个elem和'(1,2)'为第二个。 – Divakar

+0

@WillemVanOnsem我认为OP意味着使用布尔**阵列**不只是一个普通的Python列表索引。如果你将它们转换为数组,那么你会得到OP的结果。 – kmario23

回答

1

布尔矩阵或列表计算,就好像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],一个 '配对' 塞莱ction。

该块索引与阵列(或列表当量)彼此抵靠的是广播,以产生(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

+0

你怎么没有通过使用普通的python列表索引来获得'IndexError'? – kmario23

+1

我正在使用np.version:1.12.0。布尔索引处理的方式发生了变化。 – hpaulj

+0

谢谢!这个解释为我清除了它。 – kuan

1

我觉得它的工作原理如下所示:

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]) 

现在,一旦我们的索引a与布尔面具bo,我们得到:

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

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

现在,我们运用组合boc[1, 2]与行选择面膜bo

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

这里,掩模boc被施加到已经提取的行。它从第一行中选择第二个元素,从第二个行中选择第三个元素,产生[99, 99]

但是,有趣的是,如果你这样做:

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

在这种情况下,numpy的广播产生的指数[(1,1), (1,2)]