English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Pandas GroupBy

Pandas GroupByの操作例

すべてのgroupby操作は、以下のような操作を行います:

オブジェクトを分割する 関数を適用する 結果を統合する

多くの場合、データをいくつかのグループに分け、各サブセットに機能を適用します。Apply機能では、以下のような操作を行うことができます-

集約 − 汎用統計を計算する 変換 − グループ化操作 フィルタリング − ある条件でデータをフィルタリングする

今度はDataFrameオブジェクトを作成し、その上で全ての操作を行います。

#import the pandas library
 import pandas as pd
 ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
    'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
    'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
    'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
    'Points': [876,789,863,673,741,812,756,788,694,701,804,690]})
 df = pd.DataFrame(ipl_data)
 print(df)

実行結果は以下の通りです:

      ポイント ランク チーム 年
0      876      1   Riders   2014
1      789      2   Riders   2015
2      863      2   Devils   2014
3      673      3   Devils   2015
4      741      3    Kings   2014
5      812      4    kings   2015
6      756      1    Kings   2016
7      788      1    Kings   2017
8      694      2   Riders   2016
9      701      4   Royals   2014
10     804      1   Royals   2015
11     690      2   Riders   2017

データをグループに分ける

オブジェクトは分割することができます。分割方法はいくつかあります。例えば:

obj.groupby('key') obj.groupby(['key1','key2']) obj.groupby(key,axis=1)

今度は、グループ化オブジェクトをDataFrameオブジェクトに適用する方法を見てみましょう

# インポート pandas ライブラリ
 import pandas as pd
 ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
    'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
    'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
    'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
    'Points': [876,789,863,673,741,812,756,788,694,701,804,690]})
 df = pd.DataFrame(ipl_data)
 print(df.groupby('Team'))

実行結果は以下の通りです:

   

グループを確認

# インポート pandas ライブラリ
 import pandas as pd
 ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
    'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
    'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
    'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
    'Points': [876,789,863,673,741,812,756,788,694,701,804,690]})
 df = pd.DataFrame(ipl_data)
 print(df.groupby('Team').groups)

実行結果は以下の通りです:

   {'Kings': Int64Index([4, 6, 7], dtype='int64'),
 'Devils': Int64Index([2, 3], dtype='int64'),
 'Riders': Int64Index([0, 1, 8, 11], dtype='int64'),
 'Royals': Int64Index([9, 10], dtype='int64'),
 'kings' : Int64Index([5], dtype='int64})

多列でグループ化

# インポート pandas ライブラリ
 import pandas as pd
 ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
    'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
    'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
    'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
    'Points': [876,789,863,673,741,812,756,788,694,701,804,690]})
 df = pd.DataFrame(ipl_data)
 print(df.groupby(['Team','Year']).groups)

実行結果は以下の通りです:

   {('キングス',) 2014): Int64Index([4], dtype='int64'),
  ('Royals', 2014): Int64Index([9], dtype='int64'),
  (ライダーズ) 2014): Int64Index([0], dtype='int')64'),
  (ライダーズ) 2015): Int64Index([1], dtype='int64'),
  ('Kings', 2016): Int64Index([6], dtype='int64'),
  (ライダーズ) 2016): Int64Index([8], dtype='int64'),
  (ライダーズ) 2017): Int64Index([11], dtype='int64'),
  (デビルス) 2014): Int64Index([2], dtype='int64'),
  (デビルス) 2015): Int64Index([3], dtype='int64'),
  ('kings', 2015): Int64Index([5], dtype='int64'),
  ('Royals', 2015): Int64Index([10], dtype='int64'),
  ('Kings', 2017): Int64Index([7], dtype='int64})

グループの巡回

groupbyオブジェクトを持つと、itertools.objと同様にそのオブジェクトを巡回できます。

# インポート pandas ライブラリ
 import pandas as pd
 ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
    'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
    'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
    'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
    'Points': [876,789,863,673,741,812,756,788,694,701,804,690]})
 df = pd.DataFrame(ipl_data)
 grouped = df.groupby('Year')
 for name, group in grouped:
    print(name)
    print(group)

実行結果は以下の通りです:

  2014
   ポイント	ランク	チーム	年
0     876     1   Riders   2014
2     863     2   Devils   2014
4     741     3   Kings    2014
9     701     4   Royals   2014
2015
   ポイント	ランク	チーム	年
1     789     2   Riders   2015
3     673     3   Devils   2015
5     812     4    kings   2015
10    804     1   Royals   2015
2016
   ポイント	ランク	チーム	年
6     756     1    Kings   2016
8     694     2   Riders   2016
2017
   ポイント  ランク    チーム   年
7     788     1   Kings   2017
11    690     2  Riders   2017

デフォルトでは、groupbyオブジェクトのタグ名はグループ名と同じです。

グループpを選択

get_group()メソッドを使用して、グループを選択できます。

# インポート pandas ライブラリ
 import pandas as pd
 ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
    'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
    'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
    'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
    'Points': [876,789,863,673,741,812,756,788,694,701,804,690]})
 df = pd.DataFrame(ipl_data)
 grouped = df.groupby('Year')
 print(grouped.get_group(2014))

実行結果は以下の通りです:

     ポイント  ランク     チーム    年
0     876     1   Riders    2014
2     863     2   Devils    2014
4     741     3   Kings     2014
9     701     4   Royals    2014

集合体

聚合関数は各グループに対して一つの聚合値を返します。一旦グループオブジェクトが作成されると、複数の聚合操作がグループデータに対して実行できます。

合計や同等のaggメソッドを通じて合計を行うのが明確な方法です。

# インポート pandas ライブラリ
 import pandas as pd
 import numpy as np
 ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
    'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
    'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
    'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
    'Points': [876,789,863,673,741,812,756,788,694,701,804,690]})
 df = pd.DataFrame(ipl_data)
 grouped = df.groupby('Year')
 print(grouped['Points'].agg(np.mean))

実行結果は以下の通りです:

  年
2014   795.25
2015   769.50
2016   725.00
2017   739.00
名前: Points, 型: float64

各グループのサイズを確認するもう一つの方法は、size()関数を適用することです。

import pandas as pd
 import numpy as np
 ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
    'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
    'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
    'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
    'Points': [876,789,863,673,741,812,756,788,694,701,804,690]})
 df = pd.DataFrame(ipl_data)
 Python Pandasでの属性アクセス
 grouped = df.groupby('Team')
 print(grouped.agg(np.size))

実行結果は以下の通りです:

       ポイント    ランク    年
チーム
Devils        2      2      2
Kings         3      3      3
Riders        4      4      4
Royals        2      2      2
kings         1      1      1

一度に複数の聚合機能を適用

グループ化されたSeriesを介して、リストや辞書のリストや辞書を渡し、聚合を行い、DataFrameを出力することができます。-

# インポート pandas ライブラリ
 import pandas as pd
 import numpy as np
 ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
    'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
    'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
    'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
    'Points': [876,789,863,673,741,812,756,788,694,701,804,690]})
 df = pd.DataFrame(ipl_data)
 grouped = df.groupby('Team')
 print(grouped['Points'].agg([np.sum, np.mean, np.std]))

実行結果は以下の通りです:

  チーム      合計      平均          標準偏差
Devils   1536   768.000000   134.350288
Kings    2285   761.666667    24.006943
Riders   3049   762.250000    88.567771
Royals   1505   752.500000    72.831998
kings     812   812.000000          NaN

変換

グループまたは列に対する変換は、グループ化されているオブジェクトのサイズに対応するインデックスを返します。したがって、変換はグループブロックのサイズに対応する結果を返す必要があります。

# インポート pandas ライブラリ
 import pandas as pd
 import numpy as np
 ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
    'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
    'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
    'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
    'Points': [876,789,863,673,741,812,756,788,694,701,804,690]})
 df = pd.DataFrame(ipl_data)
 grouped = df.groupby('Team')
 score = lambda x: (x - x.mean())) / x.std()*10
 print(grouped.transform(score))

実行結果は以下の通りです:

     ポイント	ランク	年
0   12.843272  -15.000000  -11.618950
1   3.020286     5.000000   -3.872983
2   7.071068    -7.071068   -7.071068
3  -7.071068     7.071068    7.071068
4  -8.608621    11.547005  -10.910895
5        NaN  NaN  NaN
6  -2.360428    -5.773503    2.182179
7  10.969049    -5.773503    8.728716
8  -7.705963     5.000000    3.872983
9  -7.071068     7.071068   -7.071068
10  7.071068    -7.071068    7.071068
11 -8.157595     5.000000   11.618950

フィルタリング

フィルタリングは、定義された条件に基づいてデータをフィルタリングし、データのサブセットを返します。フィルタリング関数()はデータをフィルタリングするために使用されます。

 import pandas as pd
 import numpy as np
 ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
    'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
    'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
    'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
    'Points': [876,789,863,673,741,812,756,788,694,701,804,690]})
 df = pd.DataFrame(ipl_data)
 print(df.groupby('Team').filter(lambda x: len(x) >= 3))

実行結果は以下の通りです:

      ポイント	ランク	チーム	年
0      876     1   Riders   2014
1      789     2   Riders   2015
4      741     3   Kings    2014
6      756     1   Kings    2016
7      788     1   Kings    2017
8      694     2   Riders   2016
11     690     2   Riders   2017