421 Stimmen

Wenden Sie mehrere Funktionen auf mehrere Groupby-Spalten an

Die Docs zeigen, wie man mehrere Funktionen gleichzeitig auf ein Groupby-Objekt anwendet, indem man ein Dict mit den Ausgabespaltennamen als Schlüssel verwendet:

In [563]: grouped['D'].agg({'result1' : np.sum,
   .....:                   'result2' : np.mean})
   .....:
Out[563]: 
      result2   result1
A                      
bar -0.579846 -1.739537
foo -0.280588 -1.402938

Dies funktioniert jedoch nur bei einem Series-Groupby-Objekt. Und wenn ein Dict in ähnlicher Weise an ein Groupby-DataFrame übergeben wird, erwartet es, dass die Schlüssel die Spaltennamen sind, auf die die Funktion angewendet wird.

Was ich tun möchte, ist, mehrere Funktionen auf mehrere Spalten anzuwenden (aber bestimmte Spalten werden mehrmals bearbeitet). Außerdem werden einige Funktionen von anderen Spalten im Groupby-Objekt abhängen (wie SUMMEWENN-Funktionen). Meine aktuelle Lösung besteht darin, Spalte für Spalte vorzugehen und etwas Ähnliches wie den obigen Code zu tun, wobei Lambdas für Funktionen verwendet werden, die von anderen Zeilen abhängen. Aber das dauert lange (ich glaube, es dauert lange, ein Groupby-Objekt zu durchlaufen). Ich werde es so ändern müssen, dass ich das ganze Groupby-Objekt in einem Durchlauf durchlaufe, aber ich frage mich, ob es in pandas einen eingebauten Weg gibt, dies irgendwie sauber zu tun.

Zum Beispiel habe ich etwas Ähnliches versucht wie

grouped.agg({'C_sum' : lambda x: x['C'].sum(),
             'C_std': lambda x: x['C'].std(),
             'D_sum' : lambda x: x['D'].sum()},
             'D_sumifC3': lambda x: x['D'][x['C'] == 3].sum(), ...)

aber wie erwartet erhalte ich eine KeyError (da die Schlüssel eine Spalte sein müssen, wenn agg von einem DataFrame aufgerufen wird).

Gibt es einen eingebauten Weg, um das zu tun, was ich tun möchte, oder die Möglichkeit, dass diese Funktionalität hinzugefügt wird, oder muss ich das Groupby manuell durchlaufen?

6 Stimmen

Wenn Sie diese Frage ab 2017 besuchen, sehen Sie bitte die Antwort untenum den idiomatischen Weg zu sehen, um mehrere Spalten zusammenzufassen. Die derzeit ausgewählte Antwort hat mehrere Veraltungen darin, nämlich dass Sie nicht mehr ein Wörterbuch von Wörterbüchern verwenden können, um Spalten im Ergebnis eines groupby umzubenennen.

7voto

Mint Punkte 1898

Dies ist eine Abwandlung der Antwort von 'exans', die benannte Aggregationen verwendet. Es ist dasselbe, aber mit Argumentenentpackung, die es Ihnen ermöglicht, immer noch ein Wörterbuch an die agg-Funktion zu übergeben.

Die benannten Aggregations sind eine schöne Funktion, die auf den ersten Blick schwer zu programmieren sein könnte, da Schlüsselwörter verwendet werden, aber dies ist tatsächlich einfach mit Argumenten-/Schlüsselwort-Entpackung.

animals = pd.DataFrame({'kind': ['Katze', 'Hund', 'Katze', 'Hund'],
                         'Höhe': [9.1, 6.0, 9.5, 34.0],
                         'Gewicht': [7.9, 7.5, 9.9, 198.0]})

agg_dict = {
    "min_height": pd.NamedAgg(column='Höhe', aggfunc='min'),
    "max_height": pd.NamedAgg(column='Höhe', aggfunc='max'),
    "average_weight": pd.NamedAgg(column='Gewicht', aggfunc=np.mean)
}

animals.groupby("kind").agg(**agg_dict)

Das Ergebnis

      min_height  max_height  average_weight
kind                                        
Katze       9.1         9.5            8.90
Hund       6.0        34.0          102.75

4voto

campo Punkte 624

Die Antwort von Ted ist erstaunlich. Ich habe am Ende eine kleinere Version davon verwendet, falls es jemanden interessiert. Nützlich, wenn Sie nach einer Aggregation suchen, die von Werten aus mehreren Spalten abhängt:

ein DataFrame erstellen

df = pd.DataFrame({
    'a': [1, 2, 3, 4, 5, 6], 
    'b': [1, 1, 0, 1, 1, 0], 
    'c': ['x', 'x', 'y', 'y', 'z', 'z']
})

print(df)
   a  b  c
0  1  1  x
1  2  1  x
2  3  0  y
3  4  1  y
4  5  1  z
5  6  0  z

Gruppierung und Aggregation mit apply (Verwendung mehrerer Spalten)

print(
    df
    .groupby('c')
    .apply(lambda x: x['a'][(x['a'] > 1) & (x['b'] == 1)]
    .mean()
)
c
x    2.0
y    4.0
z    5.0

Gruppierung und Aggregation mit aggregate (Verwendung mehrerer Spalten)

Ich mag diesen Ansatz, da ich immer noch aggregate verwenden kann. Vielleicht lassen mich die Leute wissen, warum apply benötigt wird, um bei Aggregationen in Gruppen auf mehrere Spalten zuzugreifen.

Es scheint jetzt offensichtlich zu sein, aber solange Sie die Spalte von Interesse nicht direkt nach dem groupby auswählen, haben Sie Zugriff auf alle Spalten des DataFrames innerhalb Ihrer Aggregationsfunktion.

Nur Zugriff auf die ausgewählte Spalte

df.groupby('c')['a'].aggregate(lambda x: x[x > 1].mean())

Zugriff auf alle Spalten, da die Auswahl nach all dem Zauber erfolgt

df.groupby('c').aggregate(lambda x: x[(x['a'] > 1) & (x['b'] == 1)].mean())['a']

Oder ähnlich

df.groupby('c').aggregate(lambda x: x['a'][(x['a'] > 1) & (x['b'] == 1)].mean())

Ich hoffe, das hilft.

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