web-dev-qa-db-ja.com

Pandas動的な列名を使用した集計

pandasデータフレームをさまざまな数の値列で生成するスクリプトがあります。例として、このdfは

import pandas as pd
df = pd.DataFrame({
'group': ['A', 'A', 'A', 'B', 'B'],
'group_color' : ['green', 'green', 'green', 'blue', 'blue'],
'val1': [5, 2, 3, 4, 5], 
'val2' : [4, 2, 8, 5, 7]
})

  group group_color  val1  val2
0     A       green     5     4
1     A       green     2     2
2     A       green     3     8
3     B        blue     4     5
4     B        blue     5     7

私の目標は、各値列のグループ化された平均を取得することです。この特定のケース(2つの値列がある場合)では、

df.groupby('group').agg({"group_color": "first", "val1": "mean", "val2": "mean"})

      group_color      val1      val2
group                                
A           green  3.333333  4.666667
B            blue  4.500000  6.000000

ただし、問題のデータフレームに値の列(val3、val4など)が複数ある場合は機能しません。 「他のすべての列」または「名前にvalを含むすべての列」の平均を動的にとる方法はありますか?

22

より簡単に

df.groupby('group').agg(lambda x : x.head(1) if x.dtype=='object' else x.mean())
Out[63]: 
      group_color      val1      val2
group                                
A           green  3.333333  4.666667
B            blue  4.500000  6.000000
14
YOBEN_S

もしあなたの group_colorは常に1つのグループ内で同じであり、次のことができます。

df.pivot_table(index=['group','group_color'],aggfunc='mean')

出力:

                       val1      val2
group group_color                    
A     green        3.333333  4.666667
B     blue         4.500000  6.000000

それ以外の場合は、辞書を作成してaggに渡すことができます。

agg_dict = {f: 'first' if f=='group_color' else 'mean' for f in df.columns[1:]}
df.groupby('group').agg(agg_dict)

どの出力:

      group_color      val1      val2
group                                
A           green  3.333333  4.666667
B            blue  4.500000  6.000000
7
Quang Hoang

残念ながら、両方の集計関数を個別に適用する必要があります(または、"valn": "mean"valx列と同じ回数繰り返す)。 Groupby.aggは辞書を取ることができますが、キーは個別の列である必要があります。

私がこれを行う方法は、DataFrame.filterを使用して、valxの形式に従って列を持つデータフレームのサブセットを選択し、平均で集計して、集計結果を含む新しい列を割り当てることです他の列:

(df.filter(regex=r'^val').groupby(df.group).mean()
   .assign(color = df.group_color.groupby(df.group).first()))

         val1      val2    color
group                           
A      3.333333  4.666667  green
B      4.500000  6.000000   blue
6
yatu

OPのコメントごと

enter image description here

両方でグループ化できます'group'および'group_color'複数の一意のリスクがない'group_color'あたり'group'

結果として:

df.groupby(['group', 'group_color']).mean().reset_index(level=1)

      group_color      val1      val2
group                                
A           green  3.333333  4.666667
B            blue  4.500000  6.000000
4
piRSquared

次のように組み合わせることができる2つの辞書を使用できます。

df.groupby('group').agg({**{'group_color': 'first'}, **{c: 'mean' for c in df.columns if c.startswith('val')}})

この場合、1つのdictに固定集計があり、もう1つには動的な列選択があります。

1
zipa