Pandas中df.eval直接调用布尔列报错的原因咨询
问题
我有一个名为foo的DataFrame列,存储着布尔值True或False。执行df.eval("foo")时会抛出ValueError: unknown type object错误,但执行df.eval("foo == True")却能正常运行,想了解为何前者无法正常筛选True值。报错堆栈信息如下:
Traceback (most recent call last): File "<string>", line 1, in <module> File "/home/scheltie/pyvenv/mscheltienne/eeg-flow/lib/python3.10/site-packages/pandas/core/frame.py", line 4725, in eval return _eval(expr, inplace=inplace, **kwargs) File "/home/scheltie/pyvenv/mscheltienne/eeg-flow/lib/python3.10/site-packages/pandas/core/computation/eval.py", line 357, in eval ret = eng_inst.evaluate() File "/home/scheltie/pyvenv/mscheltienne/eeg-flow/lib/python3.10/site-packages/pandas/core/computation/engines.py", line 81, in evaluate res = self._evaluate() File "/home/scheltie/pyvenv/mscheltienne/eeg-flow/lib/python3.10/site-packages/pandas/core/computation/engines.py", line 121, in _evaluate return ne.evaluate(s, local_dict=scope) File "/home/scheltie/pyvenv/mscheltienne/eeg-flow/lib/python3.10/site-packages/numexpr/necompiler.py", line 975, in evaluate raise e File "/home/scheltie/pyvenv/mscheltienne/eeg-flow/lib/python3.10/site-packages/numexpr/necompiler.py", line 877, in validate signature = [(name, getType(arg)) for (name, arg) in File "/home/scheltie/pyvenv/mscheltienne/eeg-flow/lib/python3.10/site-packages/numexpr/necompiler.py", line 877, in <listcomp> signature = [(name, getType(arg)) for (name, arg) in File "/home/scheltie/pyvenv/mscheltienne/eeg-flow/lib/python3.10/site-packages/numexpr/necompiler.py", line 717, in getType raise ValueError("unknown type %s" % a.dtype.name) ValueError: unknown type object
原因分析与解决
- 核心原因:numexpr对布尔列的类型限制
pandas的eval()默认使用numexpr作为计算引擎,若你的foo列是objectdtype存储的布尔值(而非原生booldtype),numexpr无法识别object类型中的布尔值,就会抛出unknown type object错误。 - 为什么
foo == True能正常运行
执行比较操作foo == True时,pandas会先将objectdtype列转换为布尔运算上下文,numexpr处理的是比较后的明确布尔数组,而非原始object类型列,因此不会触发类型识别错误。 - 解决办法
- 转换列的 dtype 为原生布尔型:
df['foo'] = df['foo'].astype(bool),之后执行df.eval("foo")即可正常筛选。 - 继续使用
df.eval("foo == True")的写法,这是兼容objectdtype布尔列的可靠方式。 - 切换计算引擎为Python原生:
df.eval("foo", engine='python'),Python解释器能识别object中的布尔值,但性能会比numexpr差。
- 转换列的 dtype 为原生布尔型:
内容的提问来源于stack exchange,提问作者Mathieu
相关产品推荐
相关产品推荐

