200

複数回呼び出すことなく、2つの異なる集計関数f1, f2を同じ列に適用するパンダ組み込みの方法はありますか?df["returns"]agg()

データフレームの例:

import pandas as pd
import datetime as dt
import numpy as np

pd.np.random.seed(0)
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)
}) 

構文的には間違っていますが、直感的に正しい方法は次のとおりです。

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

明らかに、Pythonは重複キーを許可していません。入力を表現する他の方法はありますagg()か?おそらく、タプルのリストは[(column, function)]、同じ列に複数の関数を適用できるようにするために、より適切に機能しますか?しかしagg()、それは辞書しか受け入れないようです。

内部の両方の関数を適用するだけの補助関数を定義する以外に、これに対する回避策はありますか?(とにかく、これは集約でどのように機能しますか?)

4

3 に答える 3

240

関数をリストとして渡すだけです。

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

または辞書として:

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

非推奨の警告を回避するには:

df.groupby('dummy').agg(Mean=('returns', np.mean),
                        Sum=('returns', np.sum))
于 2012-11-27T20:57:33.097 に答える
182

TLDR; Pandasgroupby.aggには、(1)複数の列の集計、および(2)1つの列の複数の集計を指定するための新しい簡単な構文があります。したがって、パンダ> = 0.25に対してこれを行うには、

df.groupby('dummy').agg(Mean=('returns', 'mean'), Sum=('returns', 'sum'))

           Mean       Sum
dummy                    
1      0.036901  0.369012

また

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

           Mean       Sum
dummy                    
1      0.036901  0.369012

パンダ>=0.25:名前付き集計

Pandasは、GroupBy.agg名前付き集計を指定するためのより直感的な構文を優先して、の動作を変更しました。拡張機能に関する0.25のドキュメントセクションと、関連するGitHubの問題GH18366およびGH26512を参照してください。

ドキュメントから、

出力列名を制御して列固有の集計をサポートするために、pandasはGroupBy.agg()「名前付き集計」と呼ばれるの特別な構文を受け入れます。

  • キーワードは出力列名です
  • 値はタプルであり、最初の要素は選択する列であり、2番目の要素はその列に適用する集計です。Pandasは、引数が何であるかを明確にするために、pandas.NamedAggのnamedtupleにフィールド['column'、'aggfunc']を提供します。いつものように、集約は呼び出し可能または文字列エイリアスにすることができます。

キーワード引数を介してタプルを渡すことができるようになりました。タプルは。の形式に従います(<colName>, <aggFunc>)

import pandas as pd

pd.__version__                                                                                                                            
# '0.25.0.dev0+840.g989f912ee'

# Setup
df = pd.DataFrame({'kind': ['cat', 'dog', 'cat', 'dog'],
                   'height': [9.1, 6.0, 9.5, 34.0],
                   'weight': [7.9, 7.5, 9.9, 198.0]
})

df.groupby('kind').agg(
    max_height=('height', 'max'), min_weight=('weight', 'min'),)

      max_height  min_weight
kind                        
cat          9.5         7.9
dog         34.0         7.5

または、pd.NamedAgg(基本的に名前付きのタプル)を使用して、物事をより明確にすることもできます。

df.groupby('kind').agg(
    max_height=pd.NamedAgg(column='height', aggfunc='max'), 
    min_weight=pd.NamedAgg(column='weight', aggfunc='min')
)

      max_height  min_weight
kind                        
cat          9.5         7.9
dog         34.0         7.5

Seriesの場合はさらに簡単で、aggfuncをキーワード引数に渡すだけです。

df.groupby('kind')['height'].agg(max_height='max', min_height='min')    

      max_height  min_height
kind                        
cat          9.5         9.1
dog         34.0         6.0       

最後に、列名が有効なPython識別子でない場合は、解凍して辞書を使用します。

df.groupby('kind')['height'].agg(**{'max height': 'max', ...})

パンダ<0.25

0.24までのパンダの最近のバージョンでは、集計出力の列名を指定するために辞書を使用すると、次のようになります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

列の名前変更にディクショナリを使用することは、v0.20では非推奨です。パンダの最近のバージョンでは、タプルのリストを渡すだけでこれを指定できます。このように関数を指定する場合、その列のすべての関数を(name、function)ペアのタプルとして指定する必要があります。

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

        returns          
            op1       op2
dummy                    
1      0.328953  0.032895

または、

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

            op1       op2
dummy                    
1      0.328953  0.032895
于 2019-01-22T01:50:41.690 に答える
7

この作品のようなものでしょうか:

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
于 2012-09-26T01:30:08.793 に答える