Mon dataframe ressemble à
a = df['colA'].str.contains('B').groupby(df['ID']) b = df[(a.transform('sum') - a.cumsum()).eq(0)]
J'ai renvoyé toutes les lignes après la dernière occurrence de l'événement B dans chaque groupe. Le résultat sera:
ID colA 1 D 2 D 2 C
J'ai essayé
ID colA 1 B 1 D 2 B 2 D 2 C
et cela fonctionne très bien jusqu'à présent. Je me demande simplement s'il existe une approche alternative pour y parvenir?
3 Réponses :
IIUC
def yourlast(x): return x.loc[x.colA.where(df.colA.eq('B')).last_valid_index()+1:] df.groupby('ID').apply(yourlast) Out[163]: ID colA ID 1 1 1 D 2 3 2 D 4 2 C
Vous pourriez probablement ajouter group_keys = False
pour vous débarrasser du multiIndex. +1
Vous pouvez faire:
ix = (df.colA.eq('B') .cumsum() .groupby(df.ID) .apply(lambda x: x.loc[x.idxmax()+1:]).index.get_level_values(1)) df.loc[ix,:] ID colA 1 1 D 3 2 D 4 2 C
Inversez vos lignes (c'est important). Appelez ensuite groupby
et cumsum
, et prenez toutes les lignes avec une valeur de cumsum (inversée) égale à zéro.
df[df.colA.eq('B')[::-1].astype(int).groupby(df.ID).cumsum().eq(0)] ID colA 1 1 D 3 2 D 4 2 C
Cela doit-il fonctionner pour chaque ID ?
Si un groupe ne contient jamais
B
, ne doit-il rien renvoyer pour cet identifiant?oui, cela ne devrait rien renvoyer. Mais j'ai déjà filtré le dataframe pour m'assurer qu'il contient l'événement B