agg() 複数の集約値を一括で計算

複数の集約値を一度に出したいときはagg()が便利です。次のように、集約方法のリストを渡すことで複数の集約値を一度に計算します。

# 指定した列でグループ化する
grouped = df.groupby(列名)
# グループごとに複数の方法で集約する
grouped.agg(集約方法のリスト)

集約方法には、集約方法を示す文字列(最大値であれば"max"など)や関数を指定できます。本問ではまず、集約方法の文字列を指定して複数の集約値を計算する方法を学びます。

具体的な例を見てみましょう。次のような、試験結果と学習時間のデータについて考えます。


生徒ID
クラス点数学習時間(分)
ST0011-A60232
ST0021-A87345
ST0031-B66180
ST0041-A7222
ST0051-B74120
ST0061-B58215

クラスごとに各列の最大値と最小値を計算したい場合、次のように"max""min"を集約方法として指定します。

# 列「クラス」でグループ化
grouped = df.groupby("クラス")
# 最大値と最小値で集約
grouped.agg(["max", "min"])
点数学習時間(分)
maxminmaxmin
クラス
1-A876034522
1-B7458215120

複数の集約値を計算した場合、列名が「元のDataFrameの列名」と「集約方法」の2階層になります。このような複数の階層を持つ列名のことをマルチカラムといいます。

今回のクエストでは、「複数の集約値を一度に計算すると、結果の列名が2階層になる」と言う点だけ分かっていれば大丈夫です。

https://images.pyq.jp/repo/prod/pandas_groupby_agg_v2/multicolumn.jpg

SeriesGroupByのagg()

SeriesGroupByでもagg()が使えます。SeriesGroupByのagg()で複数の集約方法を指定すると、結果はマルチカラムではなく通常の列名になります。

# SeriesGroupByのagg()
grouped["点数"].agg(["max", "min"])

クラス
maxmin
1-A8760
1-B7458

列ごとに異なる集約値を使う

データ分析の実務では、列ごとに異なる集約方法を適用したい場合があります。このような場合は、agg()で キーが列名、値が集約方法の辞書 を指定します。

# 列ごとに異なる集約方法を指定する
grouped.agg({列名1: 集約方法1, 列名2: 集約方法2}

たとえば、列点数は最大値と最小値、列学習時間(分)は平均値を出したい場合、次のように指定します。

# 列「クラス」でグループ化
grouped = df.groupby("クラス")
# グループごとに点数の最大値・最小値、学習時間の平均値を出す
grouped.agg({"点数": ["max", "min"], "学習時間(分)": "mean"})
点数学習時間(分)
maxminmean
クラス
1-A8760199.666667
1-B7458171.666667

演習

import pandas as pd

# 試験結果のデータを読み込み
df = pd.read_csv("dataset/score_study_time_club.csv", index_col="生徒ID")
# 先頭5行を確認
df.head()
クラス点数学習時間(分)部活動
生徒ID
ST0011-A48.0226合唱部
ST0021-A0.024科学部
ST0031-B80.0271科学部
ST0041-ANaN45合唱部
ST0051-A68.0271美術部

今回はクラスごとに集約したいので、groupby()を使って列クラスでグループ化します。

# 列「クラス」でグループ化
grouped = df.groupby("クラス")

(1)列点数の最大値・最小値・平均値

まず、グループごとに各列の最大値・最小値を求めてみましょう。 agg()メソッドで集約方法が格納されたリストを指定すると、複数の集約値が一括で計算されます。

今回は最大値と最小値を計算したいので、[“max”, “min”]を指定します。実行すると、列名が2階層になり、列ごとに最大値・最小値が計算できることがわかります。

# グループごとに各列の最大値・最小値を計算
agg_df_1 = grouped.agg(["max", "min"])
agg_df_1
点数学習時間(分)部活動
maxminmaxminmaxmin
クラス
1-A98.00.038124美術部サッカー部
1-B83.058.0334192美術部ラグビー部

(2)列学習時間(分 の最大値・最小値・平均値

集約値に平均値(”mean”)を追加してみましょう。

次のコードを実行すると、列点数と列学習時間(分)の結果に”mean”が追加されますが、列部活動の結果は消えることがわかります。これは、文字列が格納された列部活動は平均を計算できないためです。このように、計算できない集約値が含まれていると結果から消える点に気をつけてください。

# グループごとに各列の最大値・最小値・平均値を計算
# (列「部活動」は平均値を計算できないので無視される)
agg_df_2 = grouped.agg(["max", "min", "mean"])
agg_df_2
点数学習時間(分)
maxminmeanmaxminmean
クラス
1-A98.00.066.22222238124245.1
1-B83.058.070.500000334192244.9

(3)列部活動のユニーク数

列ごとに集約値を変えることも可能です。

点数と列学習時間(分)は最大値・最小値・平均値を、列部活動はユニーク数を計算してみましょう。このような場合は、agg()キーが列名、値が集約方法となっている辞書を指定します。

# 列ごとに集約値を指定する
agg_df_3 = grouped.agg(
    {
        "点数": ["max", "min", "mean"],  # 最大値・最小値・平均値で集約
        "学習時間(分)": ["max", "min", "mean"],  # 最大値・最小値・平均値で集約
        "部活動": "nunique",  # ユニーク数で集約
    }
)
agg_df_3
点数学習時間(分)部活動
maxminmeanmaxminmeannunique
クラス
1-A98.00.066.22222238124245.15
1-B83.058.070.500000334192244.97

補足

DataFrameGroupByのdescribe()を使うと、グループごとに各列の基本統計量を計算できます。

# 列「クラス」でグループ化
grouped = df.groupby("クラス")
# クラスごとに各列の基本統計量を計算
grouped.describe()

実行結果は長いため、省略します。
なお列が長くて見づらい場合は、Tを使って行と列を入れ替えると見やすくなります。

# 縦と横を入れ替えて表示
grouped.describe().T

コメント

タイトルとURLをコピーしました