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?
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'])
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.
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
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
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.
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 .
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()
Erstellen Sie ein Gruppenobjekt und rufen Sie die folgenden Methoden auf:
grp = df.groupby(['col1', 'col2', 'col3'])
grp.max()
grp.mean()
grp.describe()