Voici un exemple simplifié de mon dataframe pandas:

     User  Binary
0   UserA       0
1   UserA       0
2   UserA       0
3   UserA       1
4   UserA       0
5   UserA       1
6   UserA       0
7   UserA       0
8   UserB       0
9   UserB       0
10  UserB       0
11  UserB       0
12  UserB       0
13  UserB       1
14  UserB       1
15  UserB       0
16  UserC       0
17  UserC       0

Pour chaque utilisateur, je voudrais supprimer toutes les lignes après la première occurrence de Binary = 1. Notez que certains utilisateurs n'ont aucun cas de Binary = 1, par exemple UserC dans cet exemple.

La sortie ressemblerait à ci-dessous:

     User  Binary
0   UserA       0
1   UserA       0
2   UserA       0
3   UserA       1
8   UserB       0
9   UserB       0
10  UserB       0
11  UserB       0
12  UserB       0
13  UserB       1
16  UserC       0
17  UserC       0
1
MRHarv 21 avril 2020 à 13:15

2 réponses

Meilleure réponse

Voici une approche utilisant groupby et la transformation avec une fonction personnalisée:

# check which Binary values are 1 and group the series by User
g = df.Binary.eq(1).groupby(df.User)
# transform to either idxmax or the last index depending
# on whether there are any Trues or not
m = g.transform(lambda x: x.idxmax() if x.any() else x.index[-1])
# index the dataframe where the index is smaler or eq m
out = df[df.index <= m]

print(out)

     User  Binary
0   UserA       0
1   UserA       0
2   UserA       0
3   UserA       1
8   UserB       0
9   UserB       0
10  UserB       0
11  UserB       0
12  UserB       0
13  UserB       1
16  UserC       0
17  UserC       0
2
yatu 21 avril 2020 à 10:40

L'idée est de tester la valeur maximale des valeurs consécutives dans l'ordre permuté par DataFrame.iloc, ce qui fonctionne aussi si seulement 0 ou seulement 1 regroupe correctement les valeurs:

def f(x):
    s = x.cumsum()
    return s.eq(s.max())
df = df[df.iloc[::-1].groupby('User')['Binary'].transform(f).sort_index()]
print (df)
     User  Binary
0   UserA       0
1   UserA       0
2   UserA       0
3   UserA       1
8   UserB       0
9   UserB       0
10  UserB       0
11  UserB       0
12  UserB       0
13  UserB       1
16  UserC       0
17  UserC       0
1
jezrael 21 avril 2020 à 10:38