web-dev-qa-db-ja.com

pandas GroupBy.agg()を使用した同じ列の複数の集計

次の(完全に過剰な)データフレームの例を考える

_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)
})
_

aggを複数回呼び出すことなく、2つの異なる集約関数を同じ列に適用する既存の組み込み方法はありますか?

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

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

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

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

87
ely

関数をリストとして単に渡すことができます:

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

dummy                    
1      0.285833  0.028583

または辞書として:

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

パンダ> = 0.25: Named Aggregation

Pandasは、_GroupBy.agg_の動作を変更して、名前付き集計を指定するためのより直感的な構文を採用しました。 .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_(本質的にはnamedtuple)を使用して、より明確にすることができます。

_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をキーワードargument.tに渡すだけです。

_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 identifiers、unpacking with dictionary with:

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

パンダ<0.25

pandas 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では、列名の変更に辞書を使用することは推奨されていません。 パンダの最新バージョンでは、タプルのリストを渡すことでより簡単に指定できます。この方法で関数を指定する場合、その列のall関数は(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
_
13
cs95

このようなものは何ですか:

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