我想用一个或条件来过滤我的数据帧,以保持特定列的值超出范围[-0.25,0.25]的行。我尝试了:

df = df[(df['col'] < -0.25) or (df['col'] > 0.25)]

但我得到了错误:

级数的真值不明确。使用a.empty、a.bool()、a.item()、.any()或.all()


当前回答

这个出色的答案很好地解释了正在发生的事情,并提供了解决方案。我想添加另一种可能适用于类似情况的解决方案:使用查询方法:

df = df.query("(col > 0.25) or (col < -0.25)")

请参见索引和选择数据。

(我目前正在使用的数据帧的一些测试表明,这种方法比在一系列布尔运算中使用逐位运算符要慢一点:2毫秒对870µs)

一条警告:至少有一种情况是列名恰好是Python表达式,这一点并不简单。我的列名为WT_38hph_IP_2、WT_38ph_input_2和log2(WT_38kph_IP_2/WT_38lph_input_2),希望执行以下查询:“(log2(WT_38hph_IP_2/WT_38hph_input_3)>1)和(WT_38h ph_IP_2>20)”

我获得了以下异常级联:

键错误:“log2”UndefinedVariableError:未定义名称“log2”ValueError:“log2”不是受支持的函数

我想发生这种情况是因为查询解析器试图从前两列中提取一些内容,而不是用第三列的名称来标识表达式。

这里提出了一种可能的解决方法。

其他回答

我遇到了同样的错误,并在PySpark数据帧中停滞了几天。由于我比较了两个字段中的整数值,所以通过用0填充na值,我成功地解决了这个问题。

如果您有多个值:

df['col'].all()

如果只有一个值:

df['col'].item()

或者,也可以使用操作员模块。更多详细信息请参见Python文档:

import operator
import numpy as np
import pandas as pd

np.random.seed(0)
df = pd.DataFrame(np.random.randn(5,3), columns=list('ABC'))
df.loc[operator.or_(df.C > 0.25, df.C < -0.25)]

          A         B         C
0  1.764052  0.400157  0.978738
1  2.240893  1.867558 -0.977278
3  0.410599  0.144044  1.454274
4  0.761038  0.121675  0.4438

您需要在panda中使用按位运算符|而不是或和&,而不是和。您不能简单地使用python中的bool语句。

对于非常复杂的过滤,请创建一个掩码并在数据帧上应用该掩码。将所有查询放入掩码并应用它,

mask = (df["col1"]>=df["col2"]) & (stock["col1"]<=df["col2"])
df_new = df[mask]

对于布尔逻辑,请使用&和|。

np.random.seed(0)
df = pd.DataFrame(np.random.randn(5,3), columns=list('ABC'))

>>> df

          A         B         C
0  1.764052  0.400157  0.978738
1  2.240893  1.867558 -0.977278
2  0.950088 -0.151357 -0.103219
3  0.410599  0.144044  1.454274
4  0.761038  0.121675  0.443863

>>> df.loc[(df.C > 0.25) | (df.C < -0.25)]

          A         B         C
0  1.764052  0.400157  0.978738
1  2.240893  1.867558 -0.977278
3  0.410599  0.144044  1.454274
4  0.761038  0.121675  0.443863

要查看正在发生的情况,您将为每个比较获得一列布尔值,例如。,

df.C > 0.25

0     True
1    False
2    False
3     True
4     True
Name: C, dtype: bool

当您有多个条件时,将返回多个列。这就是联接逻辑不明确的原因。使用和或或单独处理每一列,因此首先需要将该列减少为一个布尔值。例如,查看每个列中的任何值或所有值是否为True。

# Any value in either column is True?
(df.C > 0.25).any() or (df.C < -0.25).any()

True

# All values in either column is True?
(df.C > 0.25).all() or (df.C < -0.25).all()

False

实现相同目的的一种复杂方式是将所有这些列压缩在一起,并执行适当的逻辑。

>>> df[[any([a, b]) for a, b in zip(df.C > 0.25, df.C < -0.25)]]

          A         B         C
0  1.764052  0.400157  0.978738
1  2.240893  1.867558 -0.977278
3  0.410599  0.144044  1.454274
4  0.761038  0.121675  0.443863

有关详细信息,请参阅文档中的布尔索引。