通过检查条件进行数据帧过滤



现有数据帧:

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

最新更新