【问题标题】:pandas.eval with a boolean series with missing data带有缺少数据的布尔系列的 pandas.eval
【发布时间】:2018-04-28 13:01:09
【问题描述】:

说明

我在缺少数据的布尔系列上使用pandas.eval。

为此,我使用索引器标记非空值,并使用.loc 仅将.eval 应用于具有非缺失数据的行。

使用表达式~bool 或not(bool) 应用逻辑非运算符会返回-1 或-2。

我知道这是因为我的布尔系列由于缺少值而被转换为对象类型,但我想知道:

  • 为什么是 -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

【问题讨论】:

  • 但我不断收到值错误
  • 为什么不在评估之前强制转换为布尔值,即df.loc[indexer].astype(bool).eval('~bool')。我也很好奇你为什么得到-2和-1
  • 我无法转换,因为我可能有非布尔列(eval 适用于整个数据框,而不仅仅是一列)。例如我希望能够处理 df.eval('~bool & (num > 1)') 其中 num 是一个数字列。

标签: python pandas boolean eval missing-data


【解决方案1】:

对于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 的按位补码。


显而易见的解决方案是在额外的 setp 中使用 astype(bool) 预先将 Series 转换为 bool 类型,或者如果由于某种原因您不能在 eval 之前这样做,

>>> df.loc[indexer].eval('~bool.astype("bool")')
0    False
1     True
Name: bool, dtype: bool

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-29
    • 2016-09-16
    • 1970-01-01
    • 2021-01-27
    相关资源
    最近更新 更多