2016-09-30 91 views
0

下面是一个使用numpy的NumPy的布尔索引问题

import numpy as np 
n = 10 
arr = np.array(range(n)) 
print(arr) 
selection = [i % 2 == 0 for i in range(n)] 
print(selection) 
neg_selection = np.invert(selection) 
print(neg_selection) 

print(arr[selection]) 
print(arr[neg_selection]) 

上面的代码打印我的代码片段:

[0 1 2 3 4 5 6 7 8 9] 
[True, False, True, False, True, False, True, False, True, False] 
[False True False True False True False True False True] 
[1 0 1 0 1 0 1 0 1 0] 
[1 3 5 7 9] 

最后两个预期版画是:

[0 2 4 6 8] 
[1 3 5 7 9] 

是什么这里错了吗?

+0

你想做什么?这是一个复杂的方法来提取奇数和偶数 –

+0

不,这不是用于提取赔率和平均值。我在ndarray中有'N'个记录的数据集。我需要根据项目的索引(即协议,不允许随机混排)将它分成'test'和'train'。在我的实际案例中,数组中的每个第7项都转到'test',其余的转到'train'。在这里,我使用'2'而不是'7'和一个简单的一维数组来代替我的复杂数组来简化问题。 –

回答

2

看起来像numpy处理boolean s的list有问题。

n = 10 
arr = np.array(range(n)) 
selection = [i % 2 == 0 for i in range(n)] 
neg_selection = np.invert(selection) 

print(type(selection), arr[selection]) 
print(type(neg_selection), arr[neg_selection]) 

它生产:

<type 'list'> [1 0 1 0 1 0 1 0 1 0] 
<type 'numpy.ndarray'> [1 3 5 7 9] 

注意到,这里的问题是,由于<type 'list'>。 所以选择对象更改为numpy的阵列

selection = np.array([i % 2 == 0 for i in range(n)]) 

甚至更​​简单:

selection = arr % 2 == 0 

然后它的工作。

0

请注意,您可以(应该)写:

arr = np.arange(n) # elements of arr have the same type as n (int, float, complex, etc) 
arr = np.arange(n, dtype=int) 
arr = np.arange(n, dtype=float) 

取决于你想要的arr什么类型。

1
In [63]: arr=np.arange(10) 
In [64]: arr 
Out[64]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 

In [65]: mask = [n%2==0 for n in arr] 
In [66]: mask 
Out[66]: [True, False, True, False, True, False, True, False, True, False] 

试图指数与此列表:

In [67]: arr[mask] 
/usr/local/bin/ipython3:1: FutureWarning: in the future, boolean array-likes will be handled as a boolean array index 
    #!/usr/bin/python3 
Out[67]: array([1, 0, 1, 0, 1, 0, 1, 0, 1, 0]) 

它的治疗您的列表,指数的整数,而不是布尔值的列表;相同:

In [72]: arr[[3,0,2,0,1,0,5,0,2]] 
Out[72]: array([3, 0, 2, 0, 1, 0, 5, 0, 2]) 

我不知道为什么你使用np.invert,但后来意识到,与列表,~不起作用:

In [68]: arr[~mask] 
... 

TypeError: bad operand type for unary ~: 'list' 

invert把列表转换成一个数组并执行not

In [69]: np.invert(mask) 
Out[69]: array([False, True, False, True, False, True, False, True, False, True], dtype=bool) 
In [70]: arr[np.invert(mask)] 
Out[70]: array([1, 3, 5, 7, 9]) 

我们可以not那个数组:

In [71]: arr[~np.invert(mask)] 
Out[71]: array([0, 2, 4, 6, 8]) 

或者,如果我从一开始就创建蒙array

In [73]: mask = np.array([n%2==0 for n in arr]) 
In [74]: arr[mask] 
Out[74]: array([0, 2, 4, 6, 8]) 

所以基本上,不要试图用一个布尔值列表作为掩模。使用布尔数组。