本記事の前提
groupbyによるグループ化
pandasのgroupbyメソッドを利用し、特定の情報ごとにデータをグループ化を行い、
グループ単位で平均等を計算することはよくあると思います。
例
Python
import pandas as pd
# データフレームの作成
df = pd.DataFrame({
'group': ['A', 'B', 'A', 'B'],
'value': [1, 2, 3, 4]
})
# group列でグループ化し、value列の平均値を計算
grouped_df = df.groupby('group').mean()
print(grouped_df)
結果
css
value
group
A 2.0
B 3.0
最頻値の求め方
平均などは前述の通り、gropubyの後mean()を実行するだけですが、
最頻値はmodeをlambda関数でラップして実行する形になります。
例
Python
import pandas as pd
# データフレームの作成
df = pd.DataFrame({
'group': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C'],
'value': [1, 1, 1, 2, 2, 3, 3, 4]
})
# group列でグループ化し、value列の最頻値を計算
mode_df = df.groupby('group')['value'].apply(lambda x: x.mode())
print(mode_df)
結果
css
group
A 0 1
B 0 3
C 0 4
Name: value, dtype: int64
本題:sort_valueで、エラーとなる場合と対処
以下はエラーとならない。
例
Python
import pandas as pd
# データフレームの作成
df = pd.DataFrame({
'group': ['A', 'B', 'A', 'B'],
'value': [1, 2, 3, 4]
})
# group列でグループ化し、value列の平均値を計算後、ソートを実施
grouped_df = df.groupby('group').mean().sort_values(by='value', ascending=False)
print(grouped_df)
結果
css
value
group
B 3.0
A 2.0
一方で、以下はエラーとなる
例
Python(エラーとなる)
import pandas as pd
# データフレームの作成
df = pd.DataFrame({
'group': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C'],
'value': [1, 1, 1, 2, 2, 3, 3, 4]
})
# group列でグループ化し、value列の最頻値を計算
mode_df = df.groupby('group')['value'].apply(lambda x: x.mode()).sort_values(by = 'value')
print(mode_df)
理由は単純で、sort_valuesを付与しなかった場合の結果を見るとわかるように、
applyの結果においてはインデックスが消滅しているため。
回避策はいくつかある。
1)DataFrame型に強制的に入れる
例
Python
import pandas as pd
# データフレームの作成
df = pd.DataFrame({
'group': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C'],
'value': [1, 1, 1, 2, 2, 3, 3, 4]
})
# group列でグループ化し、value列の最頻値を計算
# その後DataFrame型に変換することでindexを復活させ、ソートを行う
mode_df = pd.DataFrame(df.groupby('group')['value'].apply(lambda x: x.mode())).sort_values(by='value')
print(mode_df)
結果
css
value
group
A 0 1
B 0 3
C 0 4
2)reset_indexを行う
例
Python
import pandas as pd
# データフレームの作成
df = pd.DataFrame({
'group': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C'],
'value': [1, 1, 1, 2, 2, 3, 3, 4]
})
# group列でグループ化し、value列の最頻値を計算
# reset_indexでindexを復活させ、ソートを行う
mode_df = df.groupby('group')['value'].apply(lambda x: x.mode()).reset_index().sort_values(by='value')
mode_df.head()
結果
group | level_1 | value | |
---|---|---|---|
0 | A | 0 | 1 |
1 | B | 0 | 3 |
2 | C | 0 | 4 |