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»?

Nilani Algiriyage
la source
Une question très similaire vient de se poser hier .. voir ici .
bdiamante
Note sur les performances, y compris les alternatives: Pandas groupby.size vs series.value_counts vs collections.Counter with multiple series
jpp

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
en attente
la source
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
Andy Hayden
la source
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

L'Adakron Gr8
la source
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.

Ted Petrou
la source
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)

À M
la source
-2

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

df.groupby(['col5','col2']).count()
seansio1995
la source