问题描述
我有一个数据框,其中 int
类型的列之一存储二进制标志模式:
import pandas as pd
df = pd.DataFrame({'flag': [1,2,4,5,7,3,9,11]})
我尝试以通常的方式(使用二进制和运算符)选择值匹配 4 的行:
df[df['flag'] & 4]
但它失败了:
KeyError: "[Int64Index([0,0],dtype='int64')] 都不在 [columns] 中"
如何实际选择匹配二进制模式的行?
解决方法
按位标志选择按您的预期工作:
>>> df['flag'] & 4
0 0
1 0
2 4
3 4
4 4
5 0
6 0
7 0
Name: flag,dtype: int64
但是,如果您将其传递给 df.loc[]
,您会要求重复获取索引 0
和 4
,或者如果您直接使用 df[]
,您会要求对于列标题为 Int64Index[...]
的列。
相反,您应该强制转换为布尔索引器:
>>> (df['flag'] & 4) != 0
0 False
1 False
2 True
3 True
4 True
5 False
6 False
7 False
Name: flag,dtype: bool
>>> df[(df['flag'] & 4) != 0]
flag
2 4
3 5
4 7
,
即使在 Pandas &
or |
is used as a logical operator to specify conditions 中,但同时使用系列作为据称逻辑运算符 results not in a Series of Boolean values but numbers 的参数。
知道您可以使用以下任何一种方法来基于二进制模式选择行:
-
由于
<int> & <FLAG>
的结果始终为<FLAG>
,因此您可以使用:df[df['flag'] & 4 == 4]
which(由于运算符的优先级)计算为:
df[(df['flag'] & 4) == 4]
-
或者,您可以使用
apply
并将结果直接映射到bool
:df[df['flag'].apply(lambda v: bool(v & FLAG))]
但这看起来确实很麻烦,而且可能会慢很多。
无论哪种情况,结果都符合预期:
flag
2 4
3 5
4 7