我在一个缺少数据的布尔序列上使用pandas.eval
。
为此,我使用索引器标记非空值,.loc
仅对具有非缺失数据的行应用.eval
。
使用表达式~bool
或not(bool)
应用逻辑非运算符会返回-1或-2。
我明白这是因为我的布尔系列由于缺少值而被转换为对象类型,但我想知道:
.eval
的正确方法是什么?这是一个使用pandas 0.20.3的可重现的例子。
df = pd.DataFrame({'bool': [True, False, None]})
bool
0 True
1 False
2 None
indexer = ~pd.isnull(df['bool'])
0 True
1 True
2 False
Name: bool, dtype: bool
df.loc[indexer].eval('~bool')
0 -2
1 -1
Name: bool, dtype: object
答案 0 :(得分:2)
对于eval
,~
将op.invert
映射为seen in the source code here。
_unary_ops_syms = '+', '-', '~', 'not' _unary_ops_funcs = op.pos, op.neg, op.invert, op.invert _unary_ops_dict = dict(zip(_unary_ops_syms, _unary_ops_funcs))
因此,当您的系列版本具有良好的旧object
类型时,您在此处看到的是
>>> ~True
-2
>>> ~False
-1
# or with your Series
>>> ~pd.Series(True, dtype='object')
0 -2
dtype: object
你想要的地方
>>> ~pd.Series(True)
0 False
dtype: bool
输出~True -> -2
和~False -> -1
是因为bool
是Python中int
的子类,而-2,-1是1和0的按位补码。
显而易见的解决方案是预先将系列转换为bool
类型,并使用额外的setp中的astype(bool)
,或者如果由于某种原因在eval
之前不能这样做,
>>> df.loc[indexer].eval('~bool.astype("bool")')
0 False
1 True
Name: bool, dtype: bool