python- pandas :在每个ID的一列中首次出现值后删除行

我使用的 dataframe 如下所示:

ID Alarm
1   1
1   2
1   3
2   3
2   1
2   2
2   4
3   4
3   2

在第一次出现Alarm = 2之后,我想分别删除每个ID的所有行.因此输出应为:

ID Alarm
1   1
1   2
2   3
2   1
2   2
3   4
3   2

最简单的方法是什么?在这种情况下可能存在 pandas 方法吗?我尝试用loc制作东西:df.loc [:df [(df [‘Alarm’] == 2)].index [0],:]),但是它在第一次出现Alarm = 2后删除了所有行,与ID无关.

最佳答案

您可以将boolean indexinggroupby创建的具有自定义功能的蒙版一起使用.

对于每个组,首先比较shift的值,因为需要先包含2.然后通过eq将其与2进行比较.但是还需要匹配每组2以下的多个值,因此需要cumsum并与0比较-删除了错误的行.

df = df[df.groupby('ID')['Alarm'].apply(lambda x: x.shift().eq(2).cumsum().eq(0))]
print (df)
   ID  Alarm
0   1      1
1   1      2
3   2      3
4   2      1
5   2      2
7   3      4
8   3      2

为了更好地了解更多数据:

df['a'] = df.groupby('ID')['Alarm'].apply(lambda x: x.shift())
df['b'] = df.groupby('ID')['Alarm'].apply(lambda x: x.shift().eq(2))
df['c'] = df.groupby('ID')['Alarm'].apply(lambda x: x.shift().eq(2).cumsum())
df['d'] = df.groupby('ID')['Alarm'].apply(lambda x: x.shift().eq(2).cumsum().eq(0))
print (df)
    ID  Alarm    a      b  c      d
0    1      1  NaN  False  0   True
1    1      2  1.0  False  0   True
2    1      2  2.0   True  1  False
3    1      2  2.0   True  2  False
4    1      3  2.0   True  3  False
5    2      3  NaN  False  0   True
6    2      1  3.0  False  0   True
7    2      2  1.0  False  0   True
8    2      4  2.0   True  1  False
9    3      4  NaN  False  0   True
10   3      2  4.0  False  0   True