我有以下数据框:
df = pd.DataFrame({"Person":[1,1,2,2,3,3,3,3], "Bank":["B1","B2","B9","B2","B6","B1","B1","B5",]})
Person Bank
0 1 B1
1 1 B2
2 2 B9
3 2 B2
4 3 B6
5 3 B1
6 3 B1
7 3 B5
我想删除B1
第一次出现之前每个人的所有行。也就是说,我要保留Bank == B1
及其后的行。
这就是我想要得到的:
Person Bank
0 1 B1
1 1 B2
5 3 B1
6 3 B1
7 3 B5
如果B1
从未发生,请清除该人的所有行。如果B1
第一次出现之前有行,我想删除它们。
答案 0 :(得分:3)
使用mask
+ ffill
m = df['Bank'].where(df['Bank'] == 'B1').groupby(df['Person']).ffill()
df[m.notnull()]
Person Bank
0 1 B1
1 1 B2
5 3 B1
6 3 B1
7 3 B5
这可以通过使组中第一次出现的所有内容都为非null值来工作。这分两个步骤完成:
1)掩盖所有无效有效的内容。
df['Bank'].where(df['Bank'] == 'B1')
0 B1
1 NaN
2 NaN
3 NaN
4 NaN
5 B1
6 B1
7 NaN
Name: Bank, dtype: object
2)逐组填写。这是答案的真正关键。这意味着B1
中第一次出现之后的所有值都将填充有效的字符串( 每个组 ),因此不会被{{ 1}}
notnull
一旦有了有效的掩码,就可以过滤掩码不为null的DataFrame。
答案 1 :(得分:2)
使用cumsum
及其bool通讯员(astype(bool)
)
df[df.groupby('Person').Bank.transform(lambda s: s.eq('B1').cumsum().astype(bool))]
Person Bank
0 1 B1
1 1 B2
5 3 B1
6 3 B1
7 3 B5
答案 2 :(得分:1)
您可以使用transform
s=(df['Bank']=='B1').groupby(df['Person'])
df[(df.index>=(s.transform('idxmax')))&s.transform('any')]
Out[305]:
Person Bank
0 1 B1
1 1 B2
5 3 B1
6 3 B1
7 3 B5