【エコンティア】経済学・データサイエンス
 
ECONTIER

【Python】groupby(”)[”].transform(‘sum / min / max’) – グルーピングの合計、最小値、最大値

使い方 – groupby(”)[”].transform(‘sum / min / max’)

今回は、Pandasライブラリでのgroupby関数で、グループ内での合計、最小値、最大値を算出します。

【Python】groupby(”)[”].transform(‘mean’) – グルーピングの平均 と同じデータセットを利用します。

 

 

import pandas as pd
import numpy as np
# CSVファイルを読み込む
df = pd.read_csv('https://raw.githubusercontent.com/econtier/sitedata/main/workprint(df[['no','personid', 'studyhour', 'av_study']])ingstudying.csv')
 

出力

no personid dt male workhour studyhour
1 1 2022/1/7 1 4 1
2 1 2022/1/8 1 5 4
3 2 2022/1/16 0 2 8
4 2 2022/1/18 0 4 3
5 2 2022/1/19 0 1 9
6 3 2022/1/21 1 3 1
7 3 2022/1/22 1 5 6
8 3 2022/1/10 1 8 7
9 4 2022/1/11 0 9 4
10 4 2022/1/13 0 10 5

ここでは、 最初のnoは通し番号、personidは生徒番号としましょう。

dtは年/月/日を表します。 maleは性別で、1=男性、0=女性を表します(ダミー変数)。

workhourはアルバイト時間(◯時間)、studyhourは勉強時間(◯時間)とします。

表の見方としては、 no1とno2は同一人物でpersonidが1の生徒のデータになります。

この生徒1は、 2022/1/7にアルバイトに4時間、勉強に1時間、

2022/1/8にアルバイトに5時間、勉強に4時間、

をしたことが観察されます。

 

 

各サブグループの合計、最小値、最大値

合計

まずはサブグループの合計を求めてみましょう。

ここでのサブグループはネスト構造としてのある1人に対して複数の観察期間がある事になっています。

つまり先程の通し番号noでの1と2はpersonid1で同一生徒として考えます。

その場合、

2022/1/7では勉強時間1時間、2022/1/8では勉強時間が4時間となり、

personid1生徒の合計勉強時間は5時間になります。

最小値

personid1での期間での最小値は、

2022/1/7では勉強時間1時間、2022/1/8では勉強時間が4時間ですので

最小値は1時間となります。

最大値

personid1での期間での最大値は、

2022/1/7では勉強時間1時間、2022/1/8では勉強時間が4時間ですので

最大値は4時間となります。

 

それでは

それぞれの生徒をまずはグルーピングして、合計、最小値、最大値を取る場合は、

Pandasの関数であるgroupbyでは、groupby().transform()を利用できます。

下記のコードでは合計、最小値、最大値を表せます。

df[‘study_total’] = df.groupby(‘personid’)[‘studyhour’].transform(‘sum’)
df[‘study_min’] = df.groupby(‘personid’)[‘studyhour’].transform(‘min’)
df[‘study_max’] = df.groupby(‘personid’)[‘studyhour’].transform(‘max’)

# personidでグループ化してstudyhourの合計、最小値、最大値を計算
df['study_total'] = df.groupby('personid')['studyhour'].transform('sum')
df['study_min'] = df.groupby('personid')['studyhour'].transform('min')
df['study_max'] = df.groupby('personid')['studyhour'].transform('max')

# personidとstudy*列を表示
df = df.sort_values('personid')
print(df[['personid', 'studyhour','study_total', 'study_min', 'study_max']])

 

出力

no personid studyhour study_total study_min study_max
1 1 1 5 1 4
2 1 4 5 1 4
3 2 8 20 3 9
4 2 3 20 3 9
5 2 9 20 3 9
6 3 1 14 1 7
7 3 6 14 1 7
8 3 7 14 1 7
9 4 4 9 4 5
10 4 5 9 4 5

 

出力結果を見てみます。

personid1の勉強時間の合計は5、最小値は1、最大値は4

personid2の勉強時間の合計は20、最小値は3、最大値は9

personid3の勉強時間の合計は14、最小値は1、最大値は7

personid4の勉強時間の合計は9、最小値は4、最大値は5

となります。

 

また、personidをグルーピングをより分かりやすくするため以下のコードでGroupごとで確認できます。

df = df.sort_values('personid')
groups = df.groupby('personid')
for group_name, group_df in groups:
    print(f"Group: {group_name}")
    print(group_df.filter(['no','studyhour','study_total','study_min', 'study_max']))
    print()

 

出力

このようにGroup:1〜Group:4で分けながら表記することができます。

Group:1
no studyhour study_total study_min study_max
1 1 5 1 4
2 4 5 1 4
Group:2
no studyhour study_total study_min study_max
3 8 20 3 9
4 3 20 3 9
5 9 20 3 9
Group:3
no studyhour study_total study_min study_max
6 1 14 1 7
7 6 14 1 7
8 7 14 1 7
Group:4
no studyhour study_total study_min study_max
9 4 9 4 5
10 5 9 4 5

また下記での表記での結果でも表せます。

 

合計

df_total = df.groupby("personid")
df_listing["studyhour"].sum()

出力

personid
1 4
2 9
3 7
4 5
Name: studyhour, dtype: int64

 

最小値

df_min = df.groupby("personid")
df_listing["studyhour"].min()

出力

personid
1 1
2 3
3 1
4 4
Name: studyhour, dtype: int64

 

最大値

df_max = df.groupby("personid")
df_listing["studyhour"].max()

出力

personid
1 4
2 9
3 7
4 5
Name: studyhour, dtype: int64

という結果でも同じく合計、最小値、最大値が求められます。