Ich habe einen Datenrahmen df und verwende mehrere Spalten von diesem zu groupby:

df['col1','col2','col3','col4'].groupby(['col1','col2']).mean()

Auf die obige Weise bekomme ich fast die Tabelle (Datenrahmen), die ich brauche. Was fehlt, ist eine zusätzliche Spalte, die die Anzahl der Zeilen in jeder Gruppe enthält. Mit anderen Worten, ich habe gemein, aber ich würde auch gerne wissen, wie viele Zahlen verwendet wurden, um diese Mittel zu erhalten. Zum Beispiel gibt es in der ersten Gruppe 8 Werte und in der zweiten 10 Werte und so weiter.

Kurz gesagt: Wie erhalte ich gruppenweise Statistiken für einen Datenrahmen?

646
Roman 15 Okt. 2013 im 19:00

7 Antworten

Beste Antwort

Für das Objekt groupby kann die Funktion agg eine Liste zu mehrere Aggregationsmethoden gleichzeitig anwenden. Dies sollte Ihnen das Ergebnis liefern, das Sie benötigen:

df[['col1', 'col2', 'col3', 'col4']].groupby(['col1', 'col2']).agg(['mean', 'count'])
385
Boud 29 Juli 2019 im 03:28

Um mehrere Statistiken zu erhalten, reduzieren Sie den Index und behalten Sie die Spaltennamen bei:

df = df.groupby(['col1','col2']).agg(['mean', 'count'])
df.columns = [ ' '.join(str(i) for i in col) for col in df.columns]
df.reset_index(inplace=True)
df

Produziert:

**enter image description here**

2
Jake Drew 13 Nov. 2019 im 01:31

Wir können es einfach tun, indem wir groupby und count verwenden. Wir sollten jedoch daran denken, reset_index () zu verwenden.

df[['col1','col2','col3','col4']].groupby(['col1','col2']).count().\
reset_index()
6
Nimesh 27 Nov. 2017 im 18:17

Schnelle Antwort:

Der einfachste Weg, um die Anzahl der Zeilen pro Gruppe zu ermitteln, ist der Aufruf von .size(), der ein Series zurückgibt:

df.groupby(['col1','col2']).size()


Normalerweise möchten Sie dieses Ergebnis als DataFrame (anstelle von Series), damit Sie Folgendes tun können:

df.groupby(['col1', 'col2']).size().reset_index(name='counts')


Wenn Sie herausfinden möchten, wie die Zeilenanzahl und andere Statistiken für jede Gruppe berechnet werden, lesen Sie weiter unten.


Detailliertes Beispiel:

Betrachten Sie den folgenden Beispieldatenrahmen:

In [2]: df
Out[2]: 
  col1 col2  col3  col4  col5  col6
0    A    B  0.20 -0.61 -0.49  1.49
1    A    B -1.53 -1.01 -0.39  1.82
2    A    B -0.44  0.27  0.72  0.11
3    A    B  0.28 -1.32  0.38  0.18
4    C    D  0.12  0.59  0.81  0.66
5    C    D -0.13 -1.65 -1.64  0.50
6    C    D -1.42 -0.11 -0.18 -0.44
7    E    F -0.00  1.42 -0.26  1.17
8    E    F  0.91 -0.47  1.35 -0.34
9    G    H  1.48 -0.63 -1.14  0.17

Verwenden wir zuerst .size(), um die Zeilenanzahl zu ermitteln:

In [3]: df.groupby(['col1', 'col2']).size()
Out[3]: 
col1  col2
A     B       4
C     D       3
E     F       2
G     H       1
dtype: int64

Verwenden wir dann .size().reset_index(name='counts'), um die Zeilenanzahl zu ermitteln:

In [4]: df.groupby(['col1', 'col2']).size().reset_index(name='counts')
Out[4]: 
  col1 col2  counts
0    A    B       4
1    C    D       3
2    E    F       2
3    G    H       1


Einschließlich Ergebnisse für weitere Statistiken

Wenn Sie Statistiken zu gruppierten Daten berechnen möchten, sieht dies normalerweise folgendermaßen aus:

In [5]: (df
   ...: .groupby(['col1', 'col2'])
   ...: .agg({
   ...:     'col3': ['mean', 'count'], 
   ...:     'col4': ['median', 'min', 'count']
   ...: }))
Out[5]: 
            col4                  col3      
          median   min count      mean count
col1 col2                                   
A    B    -0.810 -1.32     4 -0.372500     4
C    D    -0.110 -1.65     3 -0.476667     3
E    F     0.475 -0.47     2  0.455000     2
G    H    -0.630 -0.63     1  1.480000     1

Das obige Ergebnis ist aufgrund der verschachtelten Spaltenbeschriftungen und auch der Zeilenanzahl pro Spalte etwas ärgerlich.

Um mehr Kontrolle über die Ausgabe zu erhalten, teile ich die Statistiken normalerweise in einzelne Aggregationen auf, die ich dann mit join kombiniere. Es sieht aus wie das:

In [6]: gb = df.groupby(['col1', 'col2'])
   ...: counts = gb.size().to_frame(name='counts')
   ...: (counts
   ...:  .join(gb.agg({'col3': 'mean'}).rename(columns={'col3': 'col3_mean'}))
   ...:  .join(gb.agg({'col4': 'median'}).rename(columns={'col4': 'col4_median'}))
   ...:  .join(gb.agg({'col4': 'min'}).rename(columns={'col4': 'col4_min'}))
   ...:  .reset_index()
   ...: )
   ...: 
Out[6]: 
  col1 col2  counts  col3_mean  col4_median  col4_min
0    A    B       4  -0.372500       -0.810     -1.32
1    C    D       3  -0.476667       -0.110     -1.65
2    E    F       2   0.455000        0.475     -0.47
3    G    H       1   1.480000       -0.630     -0.63



Fußnoten

Der zum Generieren der Testdaten verwendete Code wird unten gezeigt:

In [1]: import numpy as np
   ...: import pandas as pd 
   ...: 
   ...: keys = np.array([
   ...:         ['A', 'B'],
   ...:         ['A', 'B'],
   ...:         ['A', 'B'],
   ...:         ['A', 'B'],
   ...:         ['C', 'D'],
   ...:         ['C', 'D'],
   ...:         ['C', 'D'],
   ...:         ['E', 'F'],
   ...:         ['E', 'F'],
   ...:         ['G', 'H'] 
   ...:         ])
   ...: 
   ...: df = pd.DataFrame(
   ...:     np.hstack([keys,np.random.randn(10,4).round(2)]), 
   ...:     columns = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6']
   ...: )
   ...: 
   ...: df[['col3', 'col4', 'col5', 'col6']] = \
   ...:     df[['col3', 'col4', 'col5', 'col6']].astype(float)
   ...: 


Haftungsausschluss:

Wenn einige der Spalten, die Sie aggregieren, Nullwerte haben, möchten Sie wirklich die Anzahl der Gruppenzeilen als unabhängige Aggregation für jede Spalte betrachten. Andernfalls werden Sie möglicherweise irregeführt, wie viele Datensätze tatsächlich zur Berechnung des Mittelwerts verwendet werden, da Pandas NaN Einträge in der Mittelwertberechnung löschen, ohne Sie darüber zu informieren.

850
Pedro M Duarte 30 Mai 2018 im 06:35

Erstellen Sie ein Gruppenobjekt und rufen Sie Methoden wie im folgenden Beispiel auf:

grp = df.groupby(['col1',  'col2',  'col3']) 

grp.max() 
grp.mean() 
grp.describe() 
0
Mahendra 11 Apr. 2019 im 14:05

Bitte versuchen Sie diesen Code

new_column=df[['col1', 'col2', 'col3', 'col4']].groupby(['col1', 'col2']).count()
df['count_it']=new_column
df

Ich denke, dieser Code fügt eine Spalte mit dem Namen "count it" hinzu, die für jede Gruppe zählt

0
Ichsan 8 Feb. 2020 im 01:34

Eine Funktion, um sie alle zu regieren: GroupBy.describe

Gibt count, mean, std und andere nützliche Statistiken pro Gruppe zurück.

df.groupby(['col1', 'col2'])['col3', 'col4'].describe()

# Setup
np.random.seed(0)
df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',
                          'foo', 'bar', 'foo', 'foo'],
                   'B' : ['one', 'one', 'two', 'three',
                          'two', 'two', 'one', 'three'],
                   'C' : np.random.randn(8),
                   'D' : np.random.randn(8)})
from IPython.display import display

with pd.option_context('precision', 2):
    display(df.groupby(['A', 'B'])['C'].describe())

           count  mean   std   min   25%   50%   75%   max
A   B                                                     
bar one      1.0  0.40   NaN  0.40  0.40  0.40  0.40  0.40
    three    1.0  2.24   NaN  2.24  2.24  2.24  2.24  2.24
    two      1.0 -0.98   NaN -0.98 -0.98 -0.98 -0.98 -0.98
foo one      2.0  1.36  0.58  0.95  1.15  1.36  1.56  1.76
    three    1.0 -0.15   NaN -0.15 -0.15 -0.15 -0.15 -0.15
    two      2.0  1.42  0.63  0.98  1.20  1.42  1.65  1.87

Um bestimmte Statistiken zu erhalten, wählen Sie sie einfach aus.

df.groupby(['A', 'B'])['C'].describe()[['count', 'mean']]

           count      mean
A   B                     
bar one      1.0  0.400157
    three    1.0  2.240893
    two      1.0 -0.977278
foo one      2.0  1.357070
    three    1.0 -0.151357
    two      2.0  1.423148

describe funktioniert für mehrere Spalten (ändern Sie ['C'] in ['C', 'D'] - oder entfernen Sie es insgesamt - und sehen Sie, was passiert. Das Ergebnis ist ein MultiIndexed-Spalten-Datenrahmen.)

Sie erhalten auch verschiedene Statistiken für Zeichenfolgendaten. Hier ist ein Beispiel:

df2 = df.assign(D=list('aaabbccc')).sample(n=100, replace=True)
with pd.option_context('precision', 2):
    display(df2.groupby(['A', 'B'])
               .describe(include='all')
               .dropna(how='all', axis=1))

              C                                                   D                
          count  mean       std   min   25%   50%   75%   max count unique top freq
A   B                                                                              
bar one    14.0  0.40  5.76e-17  0.40  0.40  0.40  0.40  0.40    14      1   a   14
    three  14.0  2.24  4.61e-16  2.24  2.24  2.24  2.24  2.24    14      1   b   14
    two     9.0 -0.98  0.00e+00 -0.98 -0.98 -0.98 -0.98 -0.98     9      1   c    9
foo one    22.0  1.43  4.10e-01  0.95  0.95  1.76  1.76  1.76    22      2   a   13
    three  15.0 -0.15  0.00e+00 -0.15 -0.15 -0.15 -0.15 -0.15    15      1   c   15
    two    26.0  1.49  4.48e-01  0.98  0.98  1.87  1.87  1.87    26      2   b   15

Weitere Informationen finden Sie in der Dokumentation.

27
cs95 12 Apr. 2019 im 09:28