使用Numpy Array,元组和省略号进行布尔索引

时间:2015-08-14 08:18:22

标签: python arrays numpy pandas tuples

我理解Numpy数组布尔索引概念的整数

In [95]: a=np.array([1, 2, 3, 2, 1, 2])

In [96]: a==1
Out[96]: array([ True, False, False, False,  True, False], dtype=bool

In [97]: a[a==1]
Out[97]: array([1, 1])

但我不明白比较是如何与Numpy Array和元组进行比较的 为什么

In [106]: a = np.array([(2011, 3), (2011, 3), (2011, 3), ..., (2015, 6), (2015, 6),
   (2015, 6), (2011, 3), (2011, 3)], dtype=object)

(...)是省略号

返回

In [107]: a==(2011,3)
Out[107]: False

我期待像

这样的数组
array([ True,  True,  True, False, False, False, False,  True,  True], dtype=bool)

如何将Numpy数组与元组与元组进行比较以获得布尔值数组?

Pandas非常简单

In [113]: pd.Series(a)==(2011, 3)
Out[113]:
0     True
1     True
2     True
3    False
4    False
5    False
6    False
7     True
8     True
dtype: bool

但我正在寻找纯粹的Numpy解决方案。

1 个答案:

答案 0 :(得分:1)

问题是a是dtype object。许多普通的数组操作都没有为这种类型的数组定义,并且通常会恢复为将数组视为列表。

In [382]: a==(2011,3)
Out[382]: False
In [383]: a.tolist()==(2011,3)
Out[383]: False

正如@Alexander指出的那样,您可以使用列表推导来逐元素地执行元素比较。此版本即使使用Ellipsis

也可以使用
In [399]: [i==(2011,3) for i in a]
Out[399]: [True, True, True, False, False, False, False, True, True]

Ellipsis没有产生标量布尔值。我可以用元组替换它,但仍然可以得到标量。

In [384]: a1=a.copy()
In [385]: a1[3]=(0,0)
...
In [387]: a1==(2011,3)
Out[387]: False

Ellipsis乍一看看起来就像是印刷品。但是pd.Series(a)==(2011, 3)产生恰好9个值的事实表明它可能不是 - 除非pd格式化只用Ellipsis替换Ellispsis只是一个元素。

a可能是In [389]: np.array([(2011, 3), (2011, 3), (2011, 3), Ellipsis, (2015, 6), (2015, 6),(2015, 6), (2011, 3), (2011, 3)]) Out[389]: array([(2011, 3), (2011, 3), (2011, 3), Ellipsis, (2015, 6), (2015, 6), (2015, 6), (2011, 3), (2011, 3)], dtype=object) 为对象dtype的原因。

np.array

没有它In [390]: np.array([(2011, 3), (2011, 3), (2011, 3), (2015, 6), (2015, 6),(2015, 6), (2011, 3), (2011, 3)]) Out[390]: array([[2011, 3], [2011, 3], [2011, 3], [2015, 6], [2015, 6], [2015, 6], [2011, 3], [2011, 3]]) 产生一个二维数组:

a1
没有省略号的

In [396]: a1.astype('i,i').view(int).reshape(-1,2) Out[396]: array([[2011, 3], [2011, 3], [2011, 3], [ 0, 0], [2015, 6], [2015, 6], [2015, 6], [2011, 3], [2011, 3]]) 可以用:

转换为2d
(...).all(axis=1)

可以使用ExpandableListView

测试2d