分组并过滤pandas数据帧

时间:2017-06-27 11:42:13

标签: python pandas dataframe filter

OID,TYPE,ResponseType
100,mod,ok
100,mod,ok
101,mod,ok
101,mod,ok
101,mod,ok
101,mod,ok
101,mod,no
102,mod,ok
102,mod,ok2
103,mod,ok
103,mod,no2

我想删除所有没有或没有2作为响应的OID。

我试过了:

dfnew = df.groupby('OID').filter(lambda x: ((x['ResponseType']=='no') | x['ResponseType']=='no2')).any() )

但是我得到了SyntaxError:语法无效

另一个apporach可能是制作要过滤的所有OID的set,然后使用它们来过滤df。df有5000000行!

预期的OP

OID,TYPE,ResponseType
100,mod,ok
100,mod,ok

102,mod,ok
102,mod,ok2

2 个答案:

答案 0 :(得分:2)

你需要为反转booelan面具添加一个^\D+$ ( - 但它确实很慢:

~

另一种解决方案,boolean indexingisin加倍:

dfnew = df.groupby('OID').filter(lambda x: ~((x['ResponseType']=='no') | 
                                             (x['ResponseType']=='no2')).any() )
                                          #here

print (dfnew)
   OID TYPE ResponseType
0  100  mod           ok
1  100  mod           ok
7  102  mod           ok
8  102  mod          ok2

使用unique

的解决方案有点慢
oids = df.loc[df['ResponseType'].isin(['no','no2']), 'OID']
print (oids)
6     101
10    103
Name: OID, dtype: int64

dfnew = df[~df['OID'].isin(oids)]
print (dfnew)
   OID TYPE ResponseType
0  100  mod           ok
1  100  mod           ok
7  102  mod           ok
8  102  mod          ok2

<强>计时

oids = df.loc[df['ResponseType'].isin(['no','no2']), 'OID'].unique()
print (oids)
[101 103]

答案 1 :(得分:0)

你可以这样做:

df[~df['OID'].isin(df[df['ResponseType'].isin(['no', 'no2'])]['OID'])]