Answers:
在or
和and
蟒蛇语句需要truth
-值。因为pandas
这些被认为是模棱两可的,所以您应该使用“按位” |
(或)或&
(和)操作:
result = result[(result['var']>0.25) | (result['var']<-0.25)]
对于此类数据结构,它们会重载以生成元素级or
(或and
)。
只是为该语句添加更多解释:
当您想获取的时bool
,将引发异常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
,但它也恰好为and
,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个语句有一些隐藏某几个Python函数bool
调用(如any
,all
,filter
,...),这些都是通常不会有问题的pandas.Series
,但出于完整性我想提一提这些。
在您的情况下,该异常并不是真正有用的,因为它没有提到正确的替代方法。对于and
和,or
您可以使用(如果您想要逐元素比较):
>>> import numpy as np
>>> np.logical_or(x, y)
或简单地|
算:
>>> x | y
>>> np.logical_and(x, y)
或简单地&
算:
>>> x & y
如果您使用的是运算符,请确保由于运算符优先级而正确设置了括号。
有几个逻辑numpy的功能,它应该工作的pandas.Series
。
如果您在执行if
或时遇到异常,则异常中提到的替代方法更适合while
。我将在下面简短地解释每个:
如果要检查您的系列是否为空:
>>> x = pd.Series([])
>>> x.empty
True
>>> x = pd.Series([1])
>>> x.empty
False
如果没有明确的布尔值解释,Python通常会将len
容器的gth(如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
如果要检查所有或任何项目是否为非零,非空或非False:
>>> 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
and
,or
和not
Python编写的。这些运算符直接使用bool
操作数返回的值。Pandas / NumPy已经以某种方式重载了该值以提高,ValueError
因为他们认为这种数据结构的真值不明确。
对于布尔逻辑,请使用&
和|
。
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
当您有多个条件时,将返回多个列。这就是为什么联接逻辑模棱两可的原因。单独使用and
或or
对待每列,因此您首先需要将该列减少为单个布尔值。例如,查看每个列中的任何值或所有值是否为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
有关更多详细信息,请参阅文档中的布尔索引。
或者,您也可以使用操作员模块。更详细的信息在这里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
这个极好的答案很好地解释了正在发生的事情并提供了解决方案。我想添加另一种可能在类似情况下适用的解决方案:使用query
方法:
result = result.query("(var > 0.25) or (var < -0.25)")
另请参见http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-query。
(一些我正在使用的数据帧的测试表明,该方法比在一系列布尔值上使用按位运算符要慢一些:2 ms vs. 870 µs)
警告:至少其中一种情况不是很简单,那就是列名恰好是python表达式。我有名为的列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)"
我获得了以下异常级联:
KeyError: 'log2'
UndefinedVariableError: name 'log2' is not defined
ValueError: "log2" is not a supported function
我猜这是因为查询解析器试图从前两列中获取内容,而不是用第三列的名称来标识表达式。
|
代替or