koji/メガネ男の日誌

日々の学び、活動状況を記録します。仕事のことは少なめ。

groupby と .agg() で DataFrameの集約を便利にするテクニック

f:id:kj_man666:20200614074750j:plain

DataFrame型をgroupbyで集約する時、agg() を使って、平均値や個数のカウントをまとめて行うテクニックです。

今回のコードはこちら

今回は、外部データ、UCIの学生の成績のデータセットを使います。

データの内容を詳しく知りたい場合は、こちらをご覧ください。

import pandas as pd
import os

# DataFrameの表示数を変更
pd.set_option('display.max_columns', 100)
pd.set_option('display.max_rows', 500)

# カレントディレクトリの参照
path = os.getcwd()

外部データをURLから読み込みます。

外部に保存されているのが zipファイルのため、zipファイルの展開も併せて行います。

# 外部データのzipファイルの読み込みに必要
import zipfile
import requests
import io

# データがあるurlを指定
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/00356/student.zip'

# データをurlから取得
r = requests.get(url, stream=True)

# zipファイル内のstudent-mat.csvをカレントディレクトリ内に展開
with zipfile.ZipFile(io.BytesIO(r.content)) as existing_zip:
    existing_zip.extract('student-mat.csv', './')
# データの読込
df = pd.read_csv(path + "\student-mat.csv", sep = ';')

必須ではありませんが、displayを使うと、まとめて1つのセルで .head()や .tail() を実行できるようになるので便利です。

# まとめて表示できるようにする
from IPython.display import display

# まとめて df を表示
display(df.head())
display(df.tail())
display(df.dtypes)

f:id:kj_man666:20200614080159p:plain

手前ミソですが、詳しくは下記サイトご参照ください。

megane-man666.hatenablog.com

このデータの性別(sex)ごとに、年齢はどうなのか、成績(G1~G3)はどうなのか、という集計をするとき、下記のようにgroupbyと.agg()を組み合わせると非常に便利です。

# 集計
df.groupby('sex').agg(
    count=('sex', 'count'),     # sex の個数をカウント
    age_mean=('age', 'mean'),   # age の平均値
    G1_mean=('G1', 'mean'),     # G1  の平均値
    G1_median=('G1', 'median'), # G1  の中央値
    G2_mean=('G2', 'sum'),      # G2  の合計
    G2_median=('G2', 'max'),    # G2  の最大値
    G3_mean=('G3', 'min'),      # G3  の最小値
    G3_median=('G3', 'std')     # G3  の標準偏差
)

f:id:kj_man666:20200614080653p:plain

以上になります、最後までお読みいただきありがとうございました。

参考サイト

medium.com

pycarnival.com