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

【Python】groupby(”)[”].transform(‘median’) – グルーピングの中央値

使い方 – groupby(”)[”].transform(‘median’)

今回は、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での3と4と5はpersonid2で同一生徒として考えます。

その場合、

2022/1/16では勉強時間(studyhour)は8時間、

2022/1/18では勉強時間が9時間、

2022/1/19では勉強時間が1時間となり、

生徒2(personid2)での勉強時間は真ん中の8時間となります。

 

データが偶数の場合は中央に位置する 2 つの数の平均値となるので

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

生徒1(personidが1)の勉強時間の中央値は2.5時間となります。

 

それぞれの生徒をまずはグルーピングして、中央値を取る場合は、

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

下記のコードでは中央値を表すコードとして

df[‘av_study’] = df.groupby(‘personid’)[‘studyhour’].transform(‘median’)

があります。personidをグルーピングし、studyhourをmedianで中央値を出しています。

 

df['median_study'] = df.groupby('personid')['studyhour'].transform('median')
# personidでソートして結果を表示
df = df.sort_values('personid')
print(df[['no','personid', 'studyhour', 'median_study']])



 

出力

no personid studyhour median_study
1 1 1 2.5
2 1 4 2.5
3 2 8 8
4 2 3 8
5 2 9 8
6 3 1 6
7 3 6 6
8 3 7 6
9 4 4 4.5
10 4 5 4.5

出力結果を見てみます。

personid1が2.5時間、personid2が8時間、personid3が6時、personid4が4.5時間が中央値となります。

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

df_median = df.groupby("personid")
df_median["studyhour"].median()

 

personid
1 2.5
2 8.0
3 6.0
4 4.5
Name: studyhour, dtype: float64

という結果でも同じく標準偏差が求められます。