it-swarm.com.de

Abrufen von Statistiken für jede Gruppe (wie Anzahl, Mittelwert usw.) mit pandas GroupBy?

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

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

Auf diese 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 meine, aber ich möchte auch 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 und so weiter.

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

336
Roman

Auf groupby -Objekten kann die agg -Funktion eine Liste erstellen, um mehrere Aggregationsmethoden anzuwenden gleichzeitig zu erstellen. Dies sollte Ihnen das Ergebnis liefern, das Sie benötigen:

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

Schnelle Antwort:

Der einfachste Weg, die Zeilenzahl 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 eines 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.


Ausführliches 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 Zeilenzahlen 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 Zeilenzahlen 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


Einschließlich der Ergebnisse für mehr 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 Spaltenbezeichnungen und der spaltenweisen Zeilenzählung 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 Code, der zum Generieren der Testdaten verwendet wird, ist 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 aufweisen, möchten Sie die Gruppenzeilenzahlen wirklich als unabhängige Aggregation für jede Spalte betrachten. Andernfalls können Sie sich irreführen lassen, wie viele Datensätze tatsächlich zur Berechnung von Dingen wie dem Mittelwert verwendet werden, da pandas NaN Einträge in der Mittelwertberechnung verwerfen, ohne Sie darüber zu informieren.

737
Pedro M Duarte

Eine Funktion, die sie alle regiert: 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 Datenrahmen mit mehreren indizierten Spalten.).

Sie erhalten auch unterschiedliche 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 .

11
cs95

Wir können es leicht 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()
5
Nimesh

Erstellen Sie ein Gruppenobjekt und rufen Sie die folgenden Methoden auf:

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

grp.max() 
grp.mean() 
grp.describe() 
0
Mahendra