Python Pandas groupby:根据值的条件过滤

Ada*_*dam 6 python pandas

考虑如下所示的数据框。

import pandas as pd

# Initialize dataframe
df1 = pd.DataFrame(columns=['bar', 'foo'])
df1['bar'] = ['001', '001', '001', '001', '002', '002', '003', '003', '003']
df1['foo'] = [-1, 0, 2, 3, -8, 1, 0, 1, 2]
>>> print df1
   bar  foo
0  001   -1
1  001    0
2  001    2
3  001    3
4  002   -8
5  002    1
6  003    0
7  003    1
8  003    2

# Lower and upper bound for desired range
lower_bound = -5
upper_bound = 5
Run Code Online (Sandbox Code Playgroud)

我想在 Pandas 中使用 groupby 返回一个数据框,该数据框过滤掉bar满足条件的行。我特别想用过滤掉行bar,如果值的一个foobar不是之间lower_boundupper_bound

在上面的示例中,bar = 002应过滤掉 的行,因为并非所有的 行bar = 002都包含foo介于-5和之间的值5(即,行索引4包含foo = -8)。此示例所需的输出如下。

# Desired output
   bar  foo
0  001   -1
1  001    0
2  001    2
3  001    3
6  003    0
7  003    1
8  003    2
Run Code Online (Sandbox Code Playgroud)

我尝试了以下方法。

# Attempted solution
grouped = df1.groupby('bar')['foo']
grouped.filter(lambda x: x < lower_bound or x > upper_bound)
Run Code Online (Sandbox Code Playgroud)

但是,这会产生一个TypeError: the filter must return a boolean result. 此外,当我希望结果返回一个数据帧对象时,这种方法可能会返回一个 groupby 对象。

Psi*_*dom 5

很可能您不会使用andandor而是矢量化&and |with pandas,并且对于您的情况,然后all()在过滤器中应用函数来构造布尔条件,这将保持bar所有相应foo值在lower_boundupper_bound之间的位置:

df1.groupby('bar').filter(lambda x: ((x.foo >= lower_bound) & (x.foo <= upper_bound)).all())

#   bar foo
#0  001 -1
#1  001  0
#2  001  2
#3  001  3
#6  003  0
#7  003  1
#8  003  2
Run Code Online (Sandbox Code Playgroud)