Pandas DataFrame Groupby deux colonnes et obtenir des comptes


166

J'ai un dataframe pandas au format suivant:

df = pd.DataFrame([[1.1, 1.1, 1.1, 2.6, 2.5, 3.4,2.6,2.6,3.4,3.4,2.6,1.1,1.1,3.3], list('AAABBBBABCBDDD'), [1.1, 1.7, 2.5, 2.6, 3.3, 3.8,4.0,4.2,4.3,4.5,4.6,4.7,4.7,4.8], ['x/y/z','x/y','x/y/z/n','x/u','x','x/u/v','x/y/z','x','x/u/v/b','-','x/y','x/y/z','x','x/u/v/w'],['1','3','3','2','4','2','5','3','6','3','5','1','1','1']]).T
df.columns = ['col1','col2','col3','col4','col5']

df:

   col1 col2 col3     col4 col5
0   1.1    A  1.1    x/y/z    1
1   1.1    A  1.7      x/y    3
2   1.1    A  2.5  x/y/z/n    3
3   2.6    B  2.6      x/u    2
4   2.5    B  3.3        x    4
5   3.4    B  3.8    x/u/v    2
6   2.6    B    4    x/y/z    5
7   2.6    A  4.2        x    3
8   3.4    B  4.3  x/u/v/b    6
9   3.4    C  4.5        -    3
10  2.6    B  4.6      x/y    5
11  1.1    D  4.7    x/y/z    1
12  1.1    D  4.7        x    1
13  3.3    D  4.8  x/u/v/w    1

Maintenant, je veux regrouper cela en deux colonnes comme suit:

df.groupby(['col5','col2']).reset_index()

Production:

             index col1 col2 col3     col4 col5
col5 col2                                      
1    A    0      0  1.1    A  1.1    x/y/z    1
     D    0     11  1.1    D  4.7    x/y/z    1
          1     12  1.1    D  4.7        x    1
          2     13  3.3    D  4.8  x/u/v/w    1
2    B    0      3  2.6    B  2.6      x/u    2
          1      5  3.4    B  3.8    x/u/v    2
3    A    0      1  1.1    A  1.7      x/y    3
          1      2  1.1    A  2.5  x/y/z/n    3
          2      7  2.6    A  4.2        x    3
     C    0      9  3.4    C  4.5        -    3
4    B    0      4  2.5    B  3.3        x    4
5    B    0      6  2.6    B    4    x/y/z    5
          1     10  2.6    B  4.6      x/y    5
6    B    0      8  3.4    B  4.3  x/u/v/b    6

Je veux obtenir le nombre de chaque ligne comme suit. Production attendue:

col5 col2 count
1    A      1
     D      3
2    B      2
etc...

Comment obtenir ma sortie attendue? Et je veux trouver le plus grand nombre pour chaque valeur «col2»?


Une question très similaire vient de se poser hier .. voir ici .
bdiamante

Réponses:


116

Suivi de la réponse de @ Andy, vous pouvez faire ce qui suit pour résoudre votre deuxième question:

In [56]: df.groupby(['col5','col2']).size().reset_index().groupby('col2')[[0]].max()
Out[56]: 
      0
col2   
A     3
B     2
C     1
D     3

1
Puis-je obtenir des valeurs "col5" pour cela comme C ... 1 ... 3?
Nilani Algiriyage

141

Vous recherchez size:

In [11]: df.groupby(['col5', 'col2']).size()
Out[11]:
col5  col2
1     A       1
      D       3
2     B       2
3     A       3
      C       1
4     B       1
5     B       2
6     B       1
dtype: int64

Pour obtenir la même réponse que waitkuo (la "deuxième question"), mais légèrement plus claire, il faut grouper par niveau:

In [12]: df.groupby(['col5', 'col2']).size().groupby(level=1).max()
Out[12]:
col2
A       3
B       2
C       1
D       3
dtype: int64

1
Je ne sais pas Pourquoi j'ai oublié ceci: O, qu'en est-il de ma deuxième question? Trouver le plus grand nombre pour chaque valeur "col2" et obtenir la valeur "col5" correspondante?
Nilani Algiriyage

23

Insérer des données dans une trame de données pandas et fournir le nom de la colonne .

import pandas as pd
df = pd.DataFrame([['A','C','A','B','C','A','B','B','A','A'], ['ONE','TWO','ONE','ONE','ONE','TWO','ONE','TWO','ONE','THREE']]).T
df.columns = [['Alphabet','Words']]
print(df)   #printing dataframe.

Voici nos données imprimées:

entrez la description de l'image ici

Pour créer un groupe de dataframe dans pandas et counter ,
vous devez fournir une colonne supplémentaire qui compte le groupement, appelons cette colonne comme " COUNTER " dans dataframe .

Comme ça:

df['COUNTER'] =1       #initially, set that counter to 1.
group_data = df.groupby(['Alphabet','Words'])['COUNTER'].sum() #sum function
print(group_data)

PRODUCTION:

entrez la description de l'image ici


9
Comment puis-je faire répéter la colonne Alphabet (par exemple A) ci-dessous et ne pas laisser les espaces dans la première colonne ??
blissweb

comment accéder à la valeur de chaque groupe qui est la somme basée sur l'alphabet et le mot?
Rahul Goyal

21

Solution idiomatique qui n'utilise qu'un seul groupby

(df.groupby(['col5', 'col2']).size() 
   .sort_values(ascending=False) 
   .reset_index(name='count') 
   .drop_duplicates(subset='col2'))

  col5 col2  count
0    3    A      3
1    1    D      3
2    5    B      2
6    3    C      1

Explication

Le résultat de la sizeméthode groupby est une série avec col5et col2dans l'index. À partir de là, vous pouvez utiliser une autre méthode groupby pour trouver la valeur maximale de chaque valeur dans, col2mais ce n'est pas nécessaire. Vous pouvez simplement trier toutes les valeurs par ordre décroissant, puis ne conserver que les lignes avec la première occurrence de col2avec la drop_duplicatesméthode.


Il n'y a pas de paramètre appelé namedans reset_index()la version actuelle de pandas: pandas.pydata.org/pandas-docs/stable/generated/…
mmBs


Ok, mon mauvais. Je l'ai utilisé lorsque je travaillais avec DataFramepas Series. Merci pour le lien.
mmBs

2

Si vous souhaitez ajouter une nouvelle colonne (par exemple 'count_column') contenant les comptes des groupes dans le dataframe:

df.count_column=df.groupby(['col5','col2']).col5.transform('count')

(J'ai choisi 'col5' car il ne contient pas de nan)


-2

Vous pouvez simplement utiliser le nombre de fonctions intégrées suivi de la fonction groupby

df.groupby(['col5','col2']).count()
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.