一个系列的真实价值是不明确的。 使用a.empty,a.bool(),a.item(),a.any()或a.all()
有问题过滤我的结果数据框与条件。 我想我的结果df提取所有列高于0.25和低于-0.25的列var值。 下面的逻辑给了我一个模棱两可的真值,但是当我在两个单独的操作中分割这个过滤时,它是有效的。 这里发生了什么? 不知道在哪里使用build议的a.empty(),a.bool(),a.item(),a.any()或a.all()。
result = result[(result['var']>0.25) or (result['var']<-0.25)]
or
和python语句需要truth
。 对于pandas
这些被认为是不明确的,所以你应该使用“按位” |
(或)或(和)操作:
result = result[(result['var']>0.25) | (result['var']<-0.25)]
对于这些types的数据结构来说,这些过载是为了产生元素or
(或) and
。
只是为了更多的解释这个陈述:
当你想获得一个pandas.Series
的bool
时抛出exception。 pandas.Series
:
>>> 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
也适用于, if
和while
):
>>> 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个语句之外,还有几个隐藏一些bool
调用(比如any
, all
, filter
,…)的python函数,这些函数通常对于pandas.Series
并不是问题,但是为了完整性,我想提一下这些。
在你的情况下,这个例外是没有用的,因为它没有提到正确的select 。 对于and
和or
你可以使用(如果你想元素明智的比较):
-
numpy.logical_or
:>>> import numpy as np >>> np.logical_or(x, y)
或简单的
|
运营商:>>> x | y
-
numpy.logical_and
:>>> np.logical_and(x, y)
或简单地
&
运营商:>>> x & y
如果您使用的是运算符,那么请确保您正确设置括号,因为运算符的优先级 。
有几个逻辑numpy函数 应该在pandas.Series
工作。
exception中提到的替代方法更适合在if
或while
时遇到它。 我会很快解释其中的每一个:
-
如果你想检查你的系列是否是空的 :
>>> x = pd.Series([]) >>> x.empty True >>> x = pd.Series([1]) >>> x.empty False
如果没有明确的布尔解释,Python通常将容器的长度(如
list
,tuple
等)解释为真值。 所以,如果你想python般的检查,你可以这样做:if x.size
或if 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 ABC 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)] ABC 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
当你有多个标准,你会得到多个列返回。 这就是连接逻辑不明确的原因。 分别使用and
或对待每个列,因此您首先需要将该列减less为单个布尔值。 例如,查看每个列中的任何值或所有值是否为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)]] ABC 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
有关更多详细信息,请参阅文档中的布尔索引 。
或者,也可以使用Operator模块。 更详细的信息在这里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)] ABC 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
这个出色的答案很好地解释了正在发生的事情并提供了解决scheme 我想添加另一个可能适用于类似情况的解决scheme:使用query
方法:
result = result.query("(var > 0.25) or (var < -0.25)")
另见http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-query 。
(一些我正在使用的数据框的testing表明,这种方法比在一系列布尔值上使用按位运算符要慢一些:2 ms vs. 870μs)
一个警告 :至less有一种情况,这不是直截了当的列名碰巧是pythonexpression式。 我有列名为WT_38hph_IP_2
, WT_38hph_input_2
和log2(WT_38hph_IP_2/WT_38hph_input_2)
并希望执行以下查询: "(log2(WT_38hph_IP_2/WT_38hph_input_2) > 1) and (WT_38hph_IP_2 > 20)"
我获得了以下exception级联:
-
KeyError: 'log2'
-
UndefinedVariableError: name 'log2' is not defined
-
ValueError: "log2" is not a supported function
我猜这是因为查询parsing器试图从前两列做出一些事情,而不是使用第三列的名称来标识expression式。
这里提出了一个可能的解决方法。