2017-02-15 109 views
1

條件濾波器考慮類似下面的數據幀。Python的熊貓GROUPBY:根據上值

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 

我想用GROUPBY在大熊貓返回與符合條件的bar濾除行的數據幀。特別是,我想篩選出與bar行;如果此barfoo的一個值是不是lower_boundupper_bound之間。

在上述示例中,與bar = 002行應該因爲並不是所有與bar = 002行的被過濾掉包含的foo-55之間的值(即,行索引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 

我試過以下方法。

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

然而,這會產生一個TypeError: the filter must return a boolean result。此外,當我想要結果返回一個數據框對象時,這種方法可能會返回一個groupby對象。

回答

1

最有可能你不會使用andor但矢量&|pandas,併爲你的情況,然後在過濾器應用於all()功能構建布爾條件下,這使bar所有相應foo之間lower_bound and upper_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