[解決済み】複数のgroupbyカラムに複数の関数を適用する
質問
その ドキュメント は、出力カラム名をキーとする dict を使って、groupby オブジェクトに一度に複数の関数を適用する方法を示しています。
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
ただし、これは Series の groupby オブジェクトに対してのみ有効です。また、groupbyのDataFrameに同様にdictが渡された場合、キーは関数が適用されるカラム名であることが期待されます。
私がやりたいことは、複数の列に対して複数の関数を適用することです(ただし、特定の列は複数回操作されます)。また いくつかの関数は、groupbyオブジェクト内の他のカラムに依存します。 (sumif関数のような)。私の現在の解決策は、列ごとに移動し、他の行に依存する関数にラムダを使用して、上記のコードのようなことを行うことです。しかし、これには長い時間がかかります(groupbyオブジェクトを繰り返し処理するのに長い時間がかかるのだと思います)。私は一回の実行でgroupbyオブジェクト全体を反復処理するように変更する必要がありますが、これをある程度きれいに行うための組み込みの方法がpandasにあるのかどうか疑問に思っています。
例えば、次のようなことをやってみた。
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(), ...)
が、案の定 KeyError が発生します (キーがカラムでなければならないのは
agg
はDataFrameから呼び出されます)。
私がやりたいことを行うための組み込みの方法、またはこの機能が追加される可能性はありますか、それとも手動でgroupbyを繰り返し実行する必要がありますか?
どのように解決するのですか?
現在受け入れられている回答の後半は、時代遅れで、2つの非推奨事項があります。まず、最も重要なことですが、辞書の辞書を
agg
groupby メソッドを使用します。次に、決して
.ix
.
もし、2つの別々のカラムを同時に操作したい場合は
apply
このメソッドでは、適用される関数に暗黙のうちに DataFrame が渡されます。上の例と同じようなデータフレームを使ってみましょう。
df = pd.DataFrame(np.random.rand(4,4), columns=list('abcd'))
df['group'] = [0, 0, 1, 1]
df
a b c d group
0 0.418500 0.030955 0.874869 0.145641 0
1 0.446069 0.901153 0.095052 0.487040 0
2 0.843026 0.936169 0.926090 0.041722 1
3 0.635846 0.439175 0.828787 0.714123 1
列名から集約関数にマッピングされたディクショナリーは、集約を実行するための完全に良い方法です。
df.groupby('group').agg({'a':['sum', 'max'],
'b':'mean',
'c':'sum',
'd': lambda x: x.max() - x.min()})
a b c d
sum max mean sum <lambda>
group
0 0.864569 0.446069 0.466054 0.969921 0.341399
1 1.478872 0.843026 0.687672 1.754877 0.672401
もし、ラムダカラムの名前が気に入らない場合は、通常の関数を使用して、カスタム名を特別に指定することができます。
__name__
属性はこのようになります。
def max_min(x):
return x.max() - x.min()
max_min.__name__ = 'Max minus Min'
df.groupby('group').agg({'a':['sum', 'max'],
'b':'mean',
'c':'sum',
'd': max_min})
a b c d
sum max mean sum Max minus Min
group
0 0.864569 0.446069 0.466054 0.969921 0.341399
1 1.478872 0.843026 0.687672 1.754877 0.672401
使用方法
apply
を作成し、Seriesを返します。
さて、複数のカラムが相互に作用する必要がある場合、以下のような方法は使えません。
agg
これは暗黙のうちにSeriesを集約関数に渡すことになります。この場合
apply
グループ全体がDataFrameとして関数に渡されます。
すべての集約をSeriesとして返すカスタム関数を1つ作ることをお勧めします。シリーズのインデックスを新しいカラムのラベルとして使用します。
def f(x):
d = {}
d['a_sum'] = x['a'].sum()
d['a_max'] = x['a'].max()
d['b_mean'] = x['b'].mean()
d['c_d_prodsum'] = (x['c'] * x['d']).sum()
return pd.Series(d, index=['a_sum', 'a_max', 'b_mean', 'c_d_prodsum'])
df.groupby('group').apply(f)
a_sum a_max b_mean c_d_prodsum
group
0 0.864569 0.446069 0.466054 0.173711
1 1.478872 0.843026 0.687672 0.630494
MultiIndexesに惚れ込んでいる人は、こんな感じでSeriesを返すこともできます。
def f_mi(x):
d = []
d.append(x['a'].sum())
d.append(x['a'].max())
d.append(x['b'].mean())
d.append((x['c'] * x['d']).sum())
return pd.Series(d, index=[['a', 'a', 'b', 'c_d'],
['sum', 'max', 'mean', 'prodsum']])
df.groupby('group').apply(f_mi)
a b c_d
sum max mean prodsum
group
0 0.864569 0.446069 0.466054 0.173711
1 1.478872 0.843026 0.687672 0.630494
関連
-
任意波形を生成してtxtで保存するためのPython実装
-
[解決済み】ImportError: PILという名前のモジュールがない
-
[解決済み] 複数の例外を1行でキャッチする(ブロックを除く)
-
[解決済み] Pandasのデータフレームで複数の列を選択する
-
[解決済み] 複数の列でgroup byを使用する
-
[解決済み] 複数の列でグループ化する
-
[解決済み] pandas GroupByを使ってグループごとの統計情報(カウント、平均値など)を取得する?
-
[解決済み] pandas が他の列の値に基づいて新しい列を作成する / 複数の列の関数を行単位で適用する
-
[解決済み】pandas GroupBy.agg()を使って同じ列を複数回集約する。)
-
[解決済み] pandasのgroupbyデータフレームにキーでアクセスする方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Pythonの非常に便利な2つのデコレーターを解説
-
PicgoのイメージベッドツールをPythonで実装する
-
Pythonによるjieba分割ライブラリ
-
Python百行で韓服サークルの画像クロールを実現する
-
Pythonの@decoratorsについてまとめてみました。
-
Pythonの画像ファイル処理用ライブラリ「Pillow」(グラフィックの詳細)
-
[解決済み】TypeError: unhashable type: 'numpy.ndarray'.
-
[解決済み】ilocが「IndexError: single positional indexer is out-of-bounds」を出す。
-
[解決済み】pygame.error: ビデオシステムが初期化されていない
-
[解決済み】Python: SyntaxError: キーワードは式になり得ない