我想用一个或条件来过滤我的数据帧,以保持特定列的值超出范围[-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()
当前回答
我遇到了同样的错误,并在PySpark数据帧中停滞了几天。由于我比较了两个字段中的整数值,所以通过用0填充na值,我成功地解决了这个问题。
其他回答
我遇到了同样的错误,并在PySpark数据帧中停滞了几天。由于我比较了两个字段中的整数值,所以通过用0填充na值,我成功地解决了这个问题。
Pandas使用位&|。此外,每个条件都应该包装在()内。
这是有效的:
data_query = data[(data['year'] >= 2005) & (data['year'] <= 2010)]
但没有括号的相同查询不会:
data_query = data[(data['year'] >= 2005 & data['year'] <= 2010)]
我将尝试给出三种最常见的方法的基准(上面也提到过):
from timeit import repeat
setup = """
import numpy as np;
import random;
x = np.linspace(0,100);
lb, ub = np.sort([random.random() * 100, random.random() * 100]).tolist()
"""
stmts = 'x[(x > lb) * (x <= ub)]', 'x[(x > lb) & (x <= ub)]', 'x[np.logical_and(x > lb, x <= ub)]'
for _ in range(3):
for stmt in stmts:
t = min(repeat(stmt, setup, number=100_000))
print('%.4f' % t, stmt)
print()
结果:
0.4808 x[(x > lb) * (x <= ub)]
0.4726 x[(x > lb) & (x <= ub)]
0.4904 x[np.logical_and(x > lb, x <= ub)]
0.4725 x[(x > lb) * (x <= ub)]
0.4806 x[(x > lb) & (x <= ub)]
0.5002 x[np.logical_and(x > lb, x <= ub)]
0.4781 x[(x > lb) * (x <= ub)]
0.4336 x[(x > lb) & (x <= ub)]
0.4974 x[np.logical_and(x > lb, x <= ub)]
但是,熊猫系列不支持*,NumPy Array比熊猫数据帧快(大约慢1000倍,见数字):
from timeit import repeat
setup = """
import numpy as np;
import random;
import pandas as pd;
x = pd.DataFrame(np.linspace(0,100));
lb, ub = np.sort([random.random() * 100, random.random() * 100]).tolist()
"""
stmts = 'x[(x > lb) & (x <= ub)]', 'x[np.logical_and(x > lb, x <= ub)]'
for _ in range(3):
for stmt in stmts:
t = min(repeat(stmt, setup, number=100))
print('%.4f' % t, stmt)
print()
结果:
0.1964 x[(x > lb) & (x <= ub)]
0.1992 x[np.logical_and(x > lb, x <= ub)]
0.2018 x[(x > lb) & (x <= ub)]
0.1838 x[np.logical_and(x > lb, x <= ub)]
0.1871 x[(x > lb) & (x <= ub)]
0.1883 x[np.logical_and(x > lb, x <= ub)]
注意:添加一行代码x=x.to_numpy()大约需要20µs。
对于喜欢%timeit的人:
import numpy as np
import random
lb, ub = np.sort([random.random() * 100, random.random() * 100]).tolist()
lb, ub
x = pd.DataFrame(np.linspace(0,100))
def asterik(x):
x = x.to_numpy()
return x[(x > lb) * (x <= ub)]
def and_symbol(x):
x = x.to_numpy()
return x[(x > lb) & (x <= ub)]
def numpy_logical(x):
x = x.to_numpy()
return x[np.logical_and(x > lb, x <= ub)]
for i in range(3):
%timeit asterik(x)
%timeit and_symbol(x)
%timeit numpy_logical(x)
print('\n')
结果:
23 µs ± 3.62 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
35.6 µs ± 9.53 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
31.3 µs ± 8.9 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
21.4 µs ± 3.35 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
21.9 µs ± 1.02 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
21.7 µs ± 500 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
25.1 µs ± 3.71 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
36.8 µs ± 18.3 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
28.2 µs ± 5.97 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
or和Python语句需要真值。对于panda,这些被认为是不明确的,因此应该使用“按位”|(或)或&(和)操作:
df = df[(df['col'] < -0.25) | (df['col'] > 0.25)]
对于这些类型的数据结构,它们被重载,以生成元素或和。
只是为了给这句话补充一些解释:
当你想得到熊猫的嘘声时,会抛出异常。系列:
>>> 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().
您到达了一个位置,在该位置运算符隐式地将操作数转换为布尔值(您使用了或,但它也适用于和、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().
除了这四个语句之外,还有几个Python函数隐藏了一些bool调用(比如any、all、filter…)。pandas.Series通常不会有问题,但为了完整起见,我想提一下这些。
在您的案例中,例外并没有真正的帮助,因为它没有提到正确的替代方案。对于和和或,如果要按元素进行比较,可以使用:
numpy.logical_或:>>>将numpy导入为np>>>np.逻辑或(x,y)或简单地使用|运算符:>>>x |年numpy.logical_and:>>>np.逻辑和(x,y)或简单地使用&运算符:>>>x和y
如果您使用的是运算符,请确保正确设置括号,因为运算符优先。
有几个逻辑NumPy函数可以在pandas.Series上工作。
如果在执行if或while时遇到异常,则异常中提到的备选方案更适合。我将很快解释其中的每一个:
如果要检查系列是否为空:>>>x=pd.系列([])>>>x.空真的>>>x=pd.系列([1])>>>x.空错误如果没有明确的布尔解释,Python通常会将容器的长度(如列表、元组等)解释为真值。因此,如果您想进行类似Python的检查,可以这样做:如果x.size或如果不是x.empty,而不是如果x。如果“系列”包含且仅包含一个布尔值:>>>x=pd.系列([100])>>>(x>50).bool()真的>>>(x<50).bool()错误如果您想检查Series的第一项也是唯一一项(例如.bool(),但它甚至适用于非布尔内容):>>>x=pd.系列([100])>>>x.项()100如果要检查所有或任何项目是否不为零、不为空或不为False:>>>x=pd.系列([0,1,2])>>>x.all()#因为一个元素为零错误>>>x.any()#,因为一个(或多个)元素非零真的
我在这个命令中遇到了一个错误:
if df != '':
pass
但当我把它改成这样时,它起了作用:
if df is not '':
pass