Filtrage de DataFrame sur des groupes où le nombre d'éléments est différent de 1


10

Je travaille avec un DataFrame ayant la structure suivante:

import pandas as pd

df = pd.DataFrame({'group':[1,1,1,2,2,2,2,3,3,3],
                   'brand':['A','B','X','C','D','X','X','E','F','X']})

print(df)

   group brand
0      1     A
1      1     B
2      1     X
3      2     C
4      2     D
5      2     X
6      2     X
7      3     E
8      3     F
9      3     X

Mon objectif est de ne voir que les groupes ayant exactement une marqueX qui leur est associée. Étant donné que le groupe numéro 2 a deux observations égales à la marque X, il doit être filtré du DataFrame résultant.

La sortie devrait ressembler à ceci:

   group brand
0      1     A
1      1     B
2      1     X
3      3     E
4      3     F
5      3     X

Je sais que je devrais faire un groupbysur la colonne de groupe, puis filtrer les groupes ayant un nombre Xdifférent de 1. La partie filtrage est l'endroit où je lutte. Toute aide serait appréciée.

Réponses:


10

Utilisez series.eqpour vérifier si brandest égal à X, puis groupez et transform sumet filtrez les groupes dont le Xnombre est égal à 1:

df[df['brand'].eq('X').groupby(df['group']).transform('sum').eq(1)]

   group brand
0      1     A
1      1     B
2      1     X
7      3     E
8      3     F
9      3     X

8

Cela devrait aussi fonctionner

df[df.groupby(['group'])['brand'].transform('sum').str.count('X').eq(1)]

Production

 group  brand
0   1   A
1   1   B
2   1   X
7   3   E
8   3   F
9   3   X

6

Colonne Groupby et appliquez un simple filtre de nombre de 'X'caractères dans le groupe égal à 1

df.groupby('group').filter(lambda x: x['brand'].str.count('X').sum() == 1)

Production

   group brand
0      1     A
1      1     B
2      1     X
7      3     E
8      3     F
9      3     X

3

Solution avec pd.crosstab

df[df['group'].map(pd.crosstab(df['group'],df['brand'])['X'].eq(1))]

#   group brand
#0      1     A
#1      1     B
#2      1     X
#7      3     E
#8      3     F
#9      3     X

Nous pouvons également utiliser DataFrame.mergeavecSeries.drop_duplicates

df.merge(df.loc[df.brand.eq('X'),'group'].drop_duplicates(keep = False),on='group')
#   group brand
#0      1     A
#1      1     B
#2      1     X
#3      3     E
#4      3     F
#5      3     X
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.