Первая идея - это группы фильтров без Active
по GroupBy.transform
и GroupBy.all
с маской по Series.ne
для неравных и цепных с инвертированной маской по ~
:
m = df['STATUS'].ne('Active')
df = df[m.groupby(df['ID']).transform('all') | ~m]
print (df)
ID STATUS
0 1 Active
2 2 Active
3 3 Completed
5 4 Active
Другая идея - преобразовать все STATUS
в упорядоченные Categorical
с, поэтому при сортировке и удалении дубликатов получают Active
, если существуют другие другие значения по приоритету с положение значений списка c
:
c = ['Active','Completed']
df['STATUS'] = pd.Categorical(df['STATUS'], ordered=True, categories=c)
df = df.sort_values(['ID','STATUS']).drop_duplicates(subset=['ID'])
print (df)
ID STATUS
0 1 Active
2 2 Active
3 3 Completed
5 4 Active