现有数据帧:
Id action date value
A enter 20/12/2021 0
A enter 20/12/2021 150
A L-1 20/12/2021 520
A L-2 20/12/2021 50
A L-2 20/12/2021 550
A L-3 20/12/2021 20
A L-4 20/12/2021 5
A L-5 20/12/2021 1
B enter 25/12/2021 2
B L-1 25/12/2021 510
B L-2 25/12/2021 6
B L-3 25/12/2021 3
C enter 26/12/2021 4
C L-1 26/12/2021 10
C L-2 26/12/2021 20
预期数据帧:
Id action date value
A L-3 20/12/2021 20
A L-4 20/12/2021 5
A L-5 20/12/2021 1
B L-2 25/12/2021 6
B L-3 25/12/2021 3
C enter 26/12/2021 4
C L-1 26/12/2021 10
C L-2 26/12/2021 20
我希望筛选出值>最后一次出现之前的行;500即,如果该值大于500并且在此之后没有其他值大于500,则仅需要保留出现在最后一个值>500
尝试了grouping Id
,但坚持应用这些条件。
如果总是有一个值>500,可以使用反向groupby.cummin
和布尔索引:
out = df.loc[df.loc[::-1, 'value'].le(500).groupby(df['Id']).cummin()]
输出:
Id action date value
5 A L-3 20/12/2021 20
6 A L-4 20/12/2021 5
7 A L-5 20/12/2021 1
10 B L-2 25/12/2021 6
11 B L-3 25/12/2021 3
中间体:
Id action date value le(500) reverse cummin
0 A enter 20/12/2021 0 True False
1 A enter 20/12/2021 150 True False
2 A L-1 20/12/2021 520 False False
3 A L-2 20/12/2021 50 True False
4 A L-2 20/12/2021 550 False False
5 A L-3 20/12/2021 20 True True
6 A L-4 20/12/2021 5 True True
7 A L-5 20/12/2021 1 True True
8 B enter 25/12/2021 2 True False
9 B L-1 25/12/2021 510 False False
10 B L-2 25/12/2021 6 True True
11 B L-3 25/12/2021 3 True True
如果不总是存在值>500,你需要第二个口罩:
g = df.loc[::-1, 'value'].le(500).groupby(df['Id'])
m1 = g.cummin() # drop rows with >500 and before
m2 = ~g.transform('all') # drop groups without value >500
out = df.loc[m1&m2]
具有以前的值:
g = df.loc[::-1, 'value'].le(500).groupby(df['Id'])
m1 = g.transform(lambda s: s.cummin().shift().bfill())
m2 = ~g.transform('all')
out = df.loc[m1&m2]
输出:
Id action date value
4 A L-2 20/12/2021 550
5 A L-3 20/12/2021 20
6 A L-4 20/12/2021 5
7 A L-5 20/12/2021 1
9 B L-1 25/12/2021 510
10 B L-2 25/12/2021 6
11 B L-3 25/12/2021 3