我想用一个或条件来过滤我的数据帧,以保持特定列的值超出范围[-0.25,0.25]的行。我尝试了:
df = df[(df['col'] < -0.25) or (df['col'] > 0.25)]
但我得到了错误:
级数的真值不明确。使用a.empty、a.bool()、a.item()、.any()或.all()
我想用一个或条件来过滤我的数据帧,以保持特定列的值超出范围[-0.25,0.25]的行。我尝试了:
df = df[(df['col'] < -0.25) or (df['col'] > 0.25)]
但我得到了错误:
级数的真值不明确。使用a.empty、a.bool()、a.item()、.any()或.all()
当前回答
或者,也可以使用操作员模块。更多详细信息请参见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
其他回答
一件小事,浪费了我的时间。
将条件(如果使用“=”,“!=”进行比较)放在括号中。未能做到这一点也会引发这种例外。
这将起作用:
df[(some condition) conditional operator (some conditions)]
这不会:
df[some condition conditional-operator some condition]
对于布尔逻辑,请使用&和|。
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
有关详细信息,请参阅文档中的布尔索引。
您需要在panda中使用按位运算符|而不是或和&,而不是和。您不能简单地使用python中的bool语句。
对于非常复杂的过滤,请创建一个掩码并在数据帧上应用该掩码。将所有查询放入掩码并应用它,
mask = (df["col1"]>=df["col2"]) & (stock["col1"]<=df["col2"])
df_new = df[mask]
这是初学者在Pandas中创建多个条件时非常常见的问题。一般来说,有两种可能的情况导致此错误:
条件1:Python运算符优先级
有一段布尔索引|索引和选择数据-panda文档解释了这一点:
另一个常见的操作是使用布尔向量来过滤数据。运算符为:| for or,&for and,~ for not。这些必须使用括号进行分组。默认情况下,Python会将df['A']>2&df['B']<3这样的表达式求值为df['A']>(2&df['B'])<3,而所需的求值顺序是(df['A']>2)&(df['B']<3)。
# Wrong
df['col'] < -0.25 | df['col'] > 0.25
# Right
(df['col'] < -0.25) | (df['col'] > 0.25)
有一些可能的方法可以去掉括号,稍后我将介绍这一点。
条件2:操作员/声明不当
正如前面的报价中所解释的,您需要使用| for or、&for and和~ for not。
# Wrong
(df['col'] < -0.25) or (df['col'] > 0.25)
# Right
(df['col'] < -0.25) | (df['col'] > 0.25)
另一种可能的情况是在if语句中使用布尔级数。
# Wrong
if pd.Series([True, False]):
pass
很明显,Python if语句接受类似布尔的表达式,而不是Pandas系列。您应该根据需要使用错误消息中列出的pandas.Series.any或方法将Series转换为值。
例如:
# Right
if df['col'].eq(0).all():
# If you want all column values equal to zero
print('do something')
# Right
if df['col'].eq(0).any():
# If you want at least one column value equal to zero
print('do something')
让我们来讨论在第一种情况下如何避开括号。
使用Pandas数学函数Pandas定义了许多数学函数,包括比较,如下所示:pandas.Series.lt()表示小于;pandas.Series.gt()表示大于;pandas.Series.le()表示小于等于;pandas.Series.ge()表示大于或等于;pandas.Series.ne()表示不相等;pandas.Series.eq()表示相等;因此,您可以使用df=df[(df['col']<-0.25)|(df['col']>0.25)]#等于df=df[df['col'].lt(-0.25)|df['col'].gt(0.25)]使用pandas.Series.between()如果要在两个值之间选择行,可以使用pandas.Series.between:df['col]。between(左,右)等于(左<=df['col'])&(df['cor']<=右);df['col].bween(左,右,包括='left)等于(左<=df['col'])&(df['cor']<右);df['col].bween(left,right,inclusive='right')等于(左<df['col'])&(df['cor']<=右);df['col].bween(左,右,包括='norther')等于(左<df['col'])&(df['cor']<右);df=df[(df['col']>-0.25)&(df['col']<0.25)]#等于df=df[df['col'].介于(-0.25,0.25,包括“任一”)]使用pandas.DataFrame.query()前面引用的文档有一章query()方法很好地解释了这一点。pandas.DataFrame.query()可以帮助您选择带有条件字符串的DataFrame。在查询字符串中,可以使用按位运算符(&和|)及其布尔表(和/或)。此外,可以省略括号,但出于可读性的原因,我不建议使用。df=df[(df['col']<-0.25)|(df['col']>0.25)]#等于df=df.query('col<-0.25或col>0.25')使用pandas.DataFrame.eval()pandas.DataFrame.eval()计算描述DataFrame列操作的字符串。因此,我们可以使用此方法来构建多个条件。语法与pandas.DataFrame.query()相同。df=df[(df['col']<-0.25)|(df['col']>0.25)]#等于df=df[df.eval('col<-0.25或col>0.25')]pandas.DataFrame.query()和pandas.DetaFrame.eval()可以做的事情比我在这里描述的要多。建议您阅读他们的文档并与他们一起玩得开心。
我在熊猫数据框架中工作时也遇到过同样的问题。
我使用过:numpy.logical_and:
在这里,我试图选择Id与41d7853匹配且degree_type不与Certification匹配的行。
如下所示:
display(df_degrees.loc[np.logical_and(df_degrees['person_id'] == '41d7853' , df_degrees['degree_type'] !='Certification')])
如果我尝试编写如下代码:
display(df_degrees.loc[df_degrees['person_id'] == '41d7853' and df_degrees['degree_type'] !='Certification'])
我们将得到错误:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
我使用了numpy.logical_,它对我很有用。