web-dev-qa-db-fra.com

Pandas DataFrame Grouper par deux colonnes et obtenir des comptes

J'ai un pandas dataframe 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 par deux colonnes comme suit:

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

Sortie:

             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 compte par chaque ligne comme suit. Production attendue:

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

Comment obtenir mon résultat attendu? Et je veux trouver le plus grand nombre pour chaque valeur 'col2'?

119
Nilani Algiriyage

Suivi par 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
81
waitingkuo

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 waitingkuo (la "deuxième question"), mais légèrement plus propre, 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
107
Andy Hayden

Insérer des données dans un pandas dataframe et en fournissant 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:

enter image description here

Pour créer un groupe de données dans pandas et un compteur ,
Vous devez fournir une colonne supplémentaire qui compte le groupement , appelons cette colonne comme suit: "COUNTER" dans le cadre de données .

Comme ça:

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

SORTIE:

enter image description here

18
The Gr8 Adakron

Solution idiomatique qui utilise un seul groupe par

(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 méthode groupby size est une série avec col5 et col2 dans l'index. À partir de là, vous pouvez utiliser une autre méthode groupby pour trouver la valeur maximale de chaque valeur dans col2, mais cela 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 col2 avec la méthode drop_duplicates.

14
Ted Petrou

Si vous souhaitez ajouter une nouvelle colonne (par exemple, "count_column") contenant le nombre de groupes dans le cadre de données:

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

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

1
Tom