807 Stimmen

Holen Sie sich Statistiken für jede Gruppe (wie Anzahl, Mittelwert usw.) mit Pandas GroupBy?

Ich habe einen DataFrame df und ich verwende mehrere Spalten daraus, um mit groupby zu gruppieren:

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

Auf diese Weise erhalte ich fast die Tabelle (DataFrame), 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 den Mittelwert, aber ich möchte auch wissen, wie viele verwendet wurden, um diese Mittelwerte zu erhalten. Zum Beispiel gibt es in der ersten Gruppe 8 Werte und in der zweiten 10 usw.

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

1495voto

Pedro M Duarte Punkte 24165

Schnelle Antwort:

Der einfachste Weg, um Zeilenanzahlen pro Gruppe zu erhalten, besteht darin, .size() aufzurufen, was eine Series zurückgibt:

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

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

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

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


Detailliertes Beispiel:

Betrachten Sie das folgende Beispiel-DataFrame:

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

Zuerst verwenden wir .size(), um die Zeilenanzahlen zu erhalten:

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

Dann verwenden wir .size().reset_index(name='counts'), um die Zeilenanzahlen zu erhalten:

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

Ergebnisse für weitere Statistiken einschließen

Wenn Sie Statistiken zu gruppierten Daten berechnen möchten, sieht es normalerweise so 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 oben gezeigte Ergebnis ist etwas mühsam zu handhaben, aufgrund der verschachtelten Spaltenbeschriftungen und auch, weil die Zeilenanzahlen auf einer pro Spalte basieren.

Um mehr Kontrolle über die Ausgabe zu erlangen, unterteile ich die Statistiken normalerweise in einzelne Aggregationen, die ich dann mit join kombiniere. Es sieht folgendermaßen aus:

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 Code, der verwendet wurde, um die Testdaten zu generieren, wird unten angezeigt:

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, NaN-Werte enthalten, sollten Sie wirklich die Gruppenzeilenanzahlen als unabhängige Aggregation für jede Spalte betrachten. Andernfalls könnten Sie darüber getäuscht werden, wie viele Datensätze tatsächlich zur Berechnung von Dingen wie dem Mittelwert verwendet werden, da Pandas NaN-Einträge bei der Mittelwertberechnung ohne Hinweis entfernt.

633voto

Zeugma Punkte 30114

Bei einem groupby-Objekt kann die agg-Funktion eine Liste entgegennehmen, um mehrere Aggregationsmethoden gleichzeitig anzuwenden. Dies sollte das gewünschte Ergebnis liefern:

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

138voto

cs95 Punkte 325143

Swiss Army Knife: GroupBy.describe

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

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 spezifische Statistiken zu erhalten, wählen Sie diese 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

Hinweis: Wenn Sie nur 1 oder 2 Statistiken berechnen müssen, ist es möglicherweise effizienter, <code>groupby.agg</code> zu verwenden und nur diese Spalten zu berechnen, da sonst eine verschwenderische Berechnung durchgeführt wird.

describe funktioniert für mehrere Spalten (ändern Sie ['C'] in ['C', 'D'] - oder entfernen Sie es vollständig - und sehen Sie, was passiert, das Ergebnis ist ein DataFrame mit mehreren Indizes).

Sie erhalten auch unterschiedliche Statistiken für Zeichendaten. 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.


pandas >= 1.1: DataFrame.value_counts

Dies ist ab pandas 1.1 verfügbar, wenn Sie nur die Größe jeder Gruppe erfassen möchten, schneidet dies die GroupBy aus und ist schneller.

df.value_counts(subset=['col1', 'col2'])

Minimalbeispiel

# 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)})

df.value_counts(['A', 'B']) 

A    B    
foo  two      2
     one      2
     three    1
bar  two      1
     three    1
     one      1
dtype: int64

Andere statistische Analysetools

Wenn Sie oben nicht finden, wonach Sie gesucht haben, enthält der Benutzerhandbuch eine umfassende Liste der unterstützten statistischen Analyse-, Korrelations- und Regressionswerkzeuge.

20voto

Jake Drew Punkte 2040

Um mehrere Statistiken zu erhalten, den Index zusammenfassen und die Spaltennamen beibehalten:

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:

**Bildbeschreibung hier eingeben**

12voto

Nimesh Punkte 157

Wir können dies leicht tun, indem wir groupby und count verwenden. Aber wir sollten nicht vergessen, reset_index() zu verwenden.

df[['col1','col2','col3','col4']].groupby(['col1','col2']).count().\
reset_index()

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X