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

时间:2017-02-15 03:59:18

标签: 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

我想在Pandas中使用groupby来返回一个数据框,该数据框会过滤掉符合条件的bar行。特别是,如果此bar的{​​{1}}值之一不在foobar之间,我希望使用lower_bound过滤掉行。

在上面的示例中,应该过滤掉upper_bound的行,因为并非bar = 002的所有行都包含bar = 002和{{1}之间的值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 。此外,当我希望结果返回数据框对象时,此方法可能会返回groupby对象。

2 个答案:

答案 0 :(得分:1)

您很可能不会使用andor,而是将&|pandas进行对比,对于您的情况,请应用{{1过滤器中的函数用于构造布尔条件,这使all()保持所有对应的bar值在 lower_bound upper_bound 之间:

foo

答案 1 :(得分:0)

Psidom的答案很好,但在大型数据集上可能会很慢。 排雷虽然可以解决,但速度很快。

df1['conditions_apply'] = (df1.foo >= lower_bound) & (df1.foo <= upper_bound)
selection = df1.groupby('bar')['conditions_apply'].min()  # any False will return False
selection = selection[selection].index.tolist()           # get all bars with Trues
df1 = df1[df1.bar.isin(selection)]                        # make selection
df1.drop(columns=['conditions_apply'], inplace=True)      # drop newly made column