2
votes

Obtenez toutes les lignes après la dernière occurrence d'une valeur spécifique dans pandas

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 commentaires

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


3 Réponses :


2
votes

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


1 commentaires

Vous pourriez probablement ajouter group_keys = False pour vous débarrasser du multiIndex. +1



2
votes

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


0 commentaires

5
votes

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


0 commentaires