在 Pandas DataFrame 中查找满足多个逻辑(布尔)条件的组

Har*_*ddy 2 python dataframe pandas

我有 3 列

Level Status     Id
0     Complete   a1
1     Start      c1
1     Complete   c1
2     Start      d1
2     Start      d2
2     Fail       d2
Run Code Online (Sandbox Code Playgroud)

我想过滤数据,其中每个级别应该只有开始和完成或开始和失败,因为两者的 id 是相同的

Level Status     Id
1     Start      c1
1     Complete   c1
2     Start      d2
2     Fail       d2
Run Code Online (Sandbox Code Playgroud)

cs9*_*s95 5

您可以使用GroupBy.transform('any')获取与具有“开始”的状态和状态也具有{“失败”,“完成”}之一的状态匹配的组,使用

status_has_start = df['Status'].eq('Start').groupby(df['Id']).transform('any')
status_has_complete_or_fail = (
    df['Status'].isin(['Complete', 'Fail']).groupby(df['Id']).transform('any'))

print (df.loc[status_has_start & status_has_complete_or_fail])

   Level    Status  Id
1      1     Start  c1
2      1  Complete  c1
4      2     Start  d2
5      2      Fail  d2 
Run Code Online (Sandbox Code Playgroud)

在哪里,

print (status_has_start)

0    False
1     True
2     True
3     True
4     True
5     True
Name: Status, dtype: bool

print (status_has_complete_or_fail)
 
0     True
1     True
2     True
3    False
4     True
5     True
Name: Status, dtype: bool
Run Code Online (Sandbox Code Playgroud)

如果你想要一个类固醇的 1 衬里,你可以运行

df.loc[pd.concat([df['Status'].eq('Start'), 
                  df['Status'].isin(['Complete', 'Fail'])], axis=1)
         .groupby([df['Level'], df['Id']])
         .transform('any')
         .all(axis=1)]

   Level    Status  Id
1      1     Start  c1
2      1  Complete  c1
4      2     Start  d2
5      2      Fail  d2
Run Code Online (Sandbox Code Playgroud)