pandas の DataFrame をグループ化するさい、groupby のキーとしてインデックスが使えます。関数やラムダ式との組み合わせが可能で、わりと自由度が高そうなので試してみます。
- 目次 -
スポンサーリンク
まずは通常の(階層化されていない)インデックス、その後、階層化インデックスで試してみます。
通常のインデックスの場合
テストデータはこんな感じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
from pandas import DataFrame df = DataFrame([10,20,30,40,50,60,70,80], index=['AA','BBB','CC','BBB','BBB','CC','AA','AA'], columns=['value']) #----------------------- # value # AA 10 # BBB 20 # CC 30 # BBB 40 # BBB 50 # CC 60 # AA 70 # AA 80 #----------------------- |
インデックスはAA、BBB、CCの3種類。2桁 と 3桁 を混在させています。
levelを指定して実行
level オプションでインデックスのレベルを指定します。
(インデックスは階層化されていないので 0 固定です)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
df.groupby(level=0) #------------------------------------ # <pandas.core.groupby.DataFrameGroupBy object at 0x00000000137454A8> #------------------------------------ # # リスト化して中をのぞくと # list(df.groupby(level=0)) #----------------------- # [('AA', value # AA 10 # AA 70 # AA 80), # ('BBB', value # BBB 20 # BBB 40 # BBB 50), # ('CC', value # CC 30 # CC 60)] #----------------------- # # 合計をとってみます # df.groupby(level=0).sum() #----------------------- # value # AA 160 # BBB 110 # CC 90 #----------------------- |
関数を適用
インデックスに関数を適用し、その結果でグルーピングすることも可能です。例としてlen関数を使って文字列長でグループ化してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# # インデックス・ラベルの長さでグルーピング # len 関数を適用 # list(df.groupby(len)) #---------------------------- # [(2, value # AA 10 # CC 30 # CC 60 # AA 70 # AA 80), # (3, value # BBB 20 # BBB 40 # BBB 50)] #---------------------------- df.groupby(len).sum() #---------------------------- # value # 2 250 # 3 110 #---------------------------- |
ラムダ式も使えます
インデックスにラムダ式を適用し、その結果でグルーピングすることも可能です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# # ラムダ式の結果でグルーピング # list(df.groupby(lambda x: x == 'AA')) #---------------------------- # [(False, value # BBB 20 # CC 30 # BBB 40 # BBB 50 # CC 60), # (True, value # AA 10 # AA 70 # AA 80)] #---------------------------- df.groupby(lambda x: x == 'AA').sum() #---------------------------- # value # False 200 # True 160 #---------------------------- |
条件を組み合わせ
関数やラムダ式は複数指定できます。
試しに、上の2つを組み合わせてグルーピングしてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# # len 関数とラムダ式の結果でグルーピング # list(df.groupby([len, lambda x: x == 'AA'])) #---------------------------- # [((2, False), value # CC 30 # CC 60), # ((2, True), value # AA 10 # AA 70 # AA 80), # ((3, False), value # BBB 20 # BBB 40 # BBB 50)] #---------------------------- df.groupby([len, lambda x: x == 'AA']).sum() #---------------------------- # value # 2 False 90 # True 160 # 3 False 110 #---------------------------- |
階層化インデックスの場合
テストデータ。
前のデータにインデックスを追加しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
df = DataFrame([10,20,30,40,50,60,70,80], index=[['AA','BBB','CC','BBB','BBB','CC','AA','AA'], [1,1,1,2,3,2,2,3]], columns=['value']) # df #----------------------------------------- # value # AA 1 10 # BBB 1 20 # CC 1 30 # BBB 2 40 # 3 50 # CC 2 60 # AA 2 70 # 3 80 #----------------------------------------- |
level オプションを使う
level オプションを指定。0 が外側、1 が内側のインデックスです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
list(df.groupby(level=0)) #----------------------------------------- # [('AA', value # AA 1 10 # 2 70 # 3 80), # ('BBB', value # BBB 1 20 # 2 40 # 3 50), # ('CC', value # CC 1 30 # 2 60)] #----------------------------------------- list(df.groupby(level=1)) #----------------------------------------- # [(1, value # AA 1 10 # BBB 1 20 # CC 1 30), # (2, value # BBB 2 40 # CC 2 60 # AA 2 70), # (3, value # BBB 3 50 # AA 3 80)] #----------------------------------------- |
ラムダ式を使う
ラムダ式を使う場合、インデックスのレベルを添え字にします
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
list(df.groupby(lambda x: x[0] == 'AA')) #----------------------------------------- # [(False, value # BBB 1 20 # CC 1 30 # BBB 2 40 # 3 50 # CC 2 60), # (True, value # AA 1 10 # 2 70 # 3 80)] #----------------------------------------- list(df.groupby(lambda x: x[1] == 2)) #----------------------------------------- # [(False, value # AA 1 10 # BBB 1 20 # CC 1 30 # BBB 3 50 # AA 3 80), # (True, value # BBB 2 40 # CC 2 60 # AA 2 70)] #----------------------------------------- |