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