我有一个包含空值的Pandas数据帧,我想用query来过滤它

data = {'Title': ['Title1', 'Title2', 'Title3', 'Title4'],
        'Subjects': ['Math; Science', 'English; Math', pd.NA, 'English']}

df_test = pd.DataFrame(data)

print(df_test)
#     Title       Subjects
# 0  Title1  Math; Science
# 1  Title2  English; Math
# 2  Title3           <NA>
# 3  Title4        English

该查询给出了一个错误:

df_test.query('Title.str.startswith("T") and Subjects.str.contains("Math")')
KeyError                                  Traceback (most recent call last)
/usr/local/lib/python3.10/dist-packages/pandas/core/computation/scope.py in resolve(self, key, is_local)
    197             if self.has_resolvers:
--> 198                 return self.resolvers[key]
    199 

36 frames KeyError: 'Series_2_0xe00x4a0x2f0xf50x420x7a0x00x0'

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
KeyError: 'Series_2_0xe00x4a0x2f0xf50x420x7a0x00x0'

The above exception was the direct cause of the following exception:

UndefinedVariableError                    Traceback (most recent call last)
/usr/local/lib/python3.10/dist-packages/pandas/core/computation/scope.py in resolve(self, key, is_local)
    209                 return self.temps[key]
    210             except KeyError as err:
--> 211                 raise UndefinedVariableError(key, is_local) from err
    212 
    213     def swapkey(self, old_key: str, new_key: str, new_value=None) -> None:

UndefinedVariableError: name 'Series_2_0xe00x4a0x2f0xf50x420x7a0x00x0' is not defined

与此查询相同:

df_test.query('Title.str.startswith("T") and Subjects.notna() and Subjects.str.contains("Math")')

这给了我想要的结果

df_test[df_test['Subjects'].notna()].query('Title.str.startswith("T") and Subjects.str.contains("Math")')
    Title   Subjects
0   Title1  Math; Science
1   Title2  English; Math

我想知道这是不是query个人的限制,或者我做错了什么.

pd.__version__
# '1.5.3'

推荐答案

使用Python 3.10(准确地说是3.10.9)和Pandas 2.2.1测试时收到相同的错误.有些令人惊讶的是,comments个版本中的@ewz93似乎对这些版本没有问题.

我可以建议两种解决方法:

  1. 在链接Series.str.contains("Math")之前添加Series.fillna:
df_test.query('Title.str.startswith("T") and Subjects.fillna("").str.contains("Math")')

    Title       Subjects
0  Title1  Math; Science
1  Title2  English; Math
  1. df.query的引擎从numexpr(默认)更改为python:
df_test.query('Title.str.startswith("T") and Subjects.str.contains("Math")', 
              engine='python')

    Title       Subjects
0  Title1  Math; Science
1  Title2  English; Math

Note

在关于df.query的文档中,他们建议不要超过engine='python',"因为与使用numexpr作为引擎相比,这是低效的".尽管如此,当在形状为1_000_000, 2)df上测试这两种方法时,方法2(重复)被证明略微更快:

# `fillna` method
573 ms ± 38.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# `engine='python' method
556 ms ± 17.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Python相关问答推荐

TARete错误:类型对象任务没有属性模型'

Pandas实际上如何对基于自定义的索引(integer和非integer)执行索引

如何检测背景有噪的图像中的正方形

如何根据参数推断对象的返回类型?

计算组中唯一值的数量

在极性中创建条件累积和

将JSON对象转换为Dataframe

未知依赖项pin—1阻止conda安装""

当我try 在django中更新模型时,模型表单数据不可见

如何在turtle中不使用write()来绘制填充字母(例如OEG)

isinstance()在使用dill.dump和dill.load后,对列表中包含的对象失败

使用特定值作为引用替换数据框行上的值

如果初始groupby找不到满足掩码条件的第一行,我如何更改groupby列,以找到它?

如何杀死一个进程,我的Python可执行文件以sudo启动?

(Python/Pandas)基于列中非缺失值的子集DataFrame

Python—为什么我的代码返回一个TypeError

如何用FFT确定频变幅值

如何获得满足掩码条件的第一行的索引?

当我定义一个继承的类时,我可以避免使用`metaclass=`吗?

PYTHON中的pd.wide_to_long比较慢