序列的真值是含糊的。请使用a.empty,a.bool(),a.item(),a.any()或a.all()。

2024-03-29 07:29:26 发布

您现在位置:Python中文网/ 问答频道 /正文

使用or条件筛选我的结果数据帧时出现问题。我希望我的结果df提取所有大于0.25小于-0.25的列var值。

下面的逻辑给了我一个不明确的真值,但是当我将这个过滤分成两个单独的操作时,它仍然有效。这里发生了什么事?不确定在哪里使用建议的a.empty(), a.bool(), a.item(),a.any() or a.all()

 result = result[(result['var']>0.25) or (result['var']<-0.25)]

Tags: or数据dfvarany逻辑resultall
3条回答

python语句需要truth值。对于pandas这些操作被认为是不明确的,因此应该使用“按位”|(或)或&(和)操作:

result = result[(result['var']>0.25) | (result['var']<-0.25)]

对于这些类型的数据结构,它们被重载,以产生按元素的or(或and)。


为了给这句话再加上一些解释:

如果要获取pandas.Seriesbool,则会引发异常:

>>> import pandas as pd
>>> x = pd.Series([1])
>>> bool(x)
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

在这里,运算符隐式地将操作数转换为bool(您使用了or,但它也适用于andifwhile):

>>> x or x
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
>>> x and x
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
>>> if x:
...     print('fun')
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
>>> while x:
...     print('fun')
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

除了这4条语句之外,还有一些python函数隐藏了一些bool调用(比如anyallfilter,…),这些通常不存在pandas.Series的问题,但为了完整起见,我想提到这些。


在您的情况下,异常并不是很有用,因为它没有提到正确的选择。对于andor,您可以使用(如果您希望按元素进行比较):

  • ^{}

    >>> import numpy as np
    >>> np.logical_or(x, y)
    

    或者简单地使用|运算符:

    >>> x | y
    
  • ^{}

    >>> np.logical_and(x, y)
    

    或者只是&运算符:

    >>> x & y
    

如果使用的是运算符,请确保由于the operator precedence而正确设置了括号。

several logical numpy functions应该在pandas.Series上工作。


如果在执行ifwhile操作时遇到异常,则异常中提到的替代项更适合。我将很快解释这些:

  • 如果要检查序列是否为空:

    >>> x = pd.Series([])
    >>> x.empty
    True
    >>> x = pd.Series([1])
    >>> x.empty
    False
    

    如果没有明确的布尔解释,Python通常将容器的length(比如listtuple,…)解释为真值。因此,如果您想要类似python的检查,可以执行:if x.sizeif not x.empty而不是if x

  • 如果Series包含一个且仅包含一个布尔值:

    >>> x = pd.Series([100])
    >>> (x > 50).bool()
    True
    >>> (x < 50).bool()
    False
    
  • 如果要检查序列中的第一个也是唯一的项(例如.bool(),但即使对非布尔内容也有效):

    >>> x = pd.Series([100])
    >>> x.item()
    100
    
  • 如果要检查全部任何项是否不为零、不为空或不为假:

    >>> x = pd.Series([0, 1, 2])
    >>> x.all()   # because one element is zero
    False
    >>> x.any()   # because one (or more) elements are non-zero
    True
    

对于布尔逻辑,使用&|

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

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

# 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

有关详细信息,请参阅文档中的Boolean Indexing

或者,也可以使用操作员模块。这里有更详细的信息Python docs

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

相关问题 更多 >