it-swarm.com.de

Mehrere Aggregationen derselben Spalte mit Pandas GroupBy.agg ()

Gegeben sei das folgende (total overkill) Datenrahmen-Beispiel

import pandas as pd
import datetime as dt
df = pd.DataFrame({
         "date"    :  [dt.date(2012, x, 1) for x in range(1, 11)], 
         "returns" :  0.05 * np.random.randn(10), 
         "dummy"   :  np.repeat(1, 10)
})

gibt es eine integrierte Möglichkeit, zwei verschiedene Aggregationsfunktionen auf dieselbe Spalte anzuwenden, ohne agg mehrmals aufrufen zu müssen? 

Der syntaktisch falsche, aber intuitiv richtige Weg wäre:

# Assume `function1` and `function2` are defined for aggregating.
df.groupby("dummy").agg({"returns":function1, "returns":function2})

Offensichtlich erlaubt Python keine doppelten Schlüssel. Gibt es eine andere Möglichkeit, die Eingabe in agg auszudrücken? Vielleicht würde eine Liste von Tupeln [(column, function)] besser funktionieren, damit mehrere Funktionen auf dieselbe Spalte angewendet werden können. Aber es scheint, als würde nur ein Wörterbuch akzeptiert.

Gibt es eine Problemumgehung dafür, neben der Definition einer Hilfsfunktion, die nur beide Funktionen in ihr anwendet? (Wie würde das überhaupt mit Aggregation funktionieren?)

61
ely

Sie können die Funktionen einfach als Liste übergeben:

In [20]: df.groupby("dummy").agg({"returns": [np.mean, np.sum]})
Out[20]: 
        returns          
            sum      mean

dummy                    
1      0.285833  0.028583

oder als Wörterbuch:

In [21]: df.groupby('dummy').agg({'returns':
                                  {'Mean': np.mean, 'Sum': np.sum}})
Out[21]: 
        returns          
            Sum      Mean
dummy                    
1      0.285833  0.028583
82
bmu

Möchte so etwas funktionieren:

In [7]: df.groupby('dummy').returns.agg({'func1' : lambda x: x.sum(), 'func2' : lambda x: x.prod()})
Out[7]: 
              func2     func1
dummy                        
1     -4.263768e-16 -0.188565
5
Chang She

Ein naheliegender Weg, dies zu tun, besteht darin, ein Wörterbuch anzugeben, das Spaltennamen einer Liste von Funktionen zuordnet, mit denen zusammengefasst werden kann:

df.groupby("dummy").agg({'returns': [function1, function2]})

df.groupby("dummy").agg({'returns': ['sum', 'mean']})

        returns          
            sum      mean
dummy                    
1      0.328953  0.032895

Wenn Ihre Funktionen jedoch nur für die Spalte verwendet werden, ist die Syntax etwas einfacher - ein Wörterbuch wird nicht benötigt, wenn Sie eine Reihe zusammenstellen:

df.groupby("dummy")['returns'].agg([function1, function2])

df.groupby('dummy')['returns'].agg(['sum', 'mean'])

            sum      mean
dummy                    
1      0.328953  0.032895

Dadurch entfällt auch der MultiIndex in der Ausgabe.


Wenn Sie in neueren Pandas-Versionen ein Wörterbuch zur Angabe von Spaltennamen für die Aggregationsausgabe verwenden, erhalten Sie eine FutureWarning:

df.groupby('dummy').agg({'returns': {'Mean': 'mean', 'Sum': 'sum'}})
# FutureWarning: using a dict with renaming is deprecated and will be removed 
# in a future version

Die Verwendung eines Wörterbuchs zum Umbenennen von Spalten ist in v0.20 veraltet. Bei neueren Versionen von Pandas kann dies einfacher durch Übergeben einer Liste von Tupeln angegeben werden. Wenn Sie die Funktionen auf diese Weise angeben, müssen all - Funktionen für diese Spalte als Tupel von (Name, Funktion) Paaren angegeben werden.

df.groupby("dummy").agg({'returns': [('op1', 'sum'), ('op2', 'mean')]})

        returns          
            op1       op2
dummy                    
1      0.328953  0.032895

Oder,

df.groupby("dummy")['returns'].agg([('op1', 'sum'), ('op2', 'mean')])

            op1       op2
dummy                    
1      0.328953  0.032895
0
coldspeed