Pandas groupby.agg() 関数

Pandas 常用関数


groupby.agg()Pandas の中でも最も強力な集約関数の1つであり、グループ化されたデータに対して複数の異なる集約関数を同時に適用することができます。

とsum()、mean()などの単一集約関数とは異なり、agg()複数の統計指標を一度に計算でき、たとえば各グループの合計、平均、最大値、最小値などを同時に計算できます。

データ分析では、データに対して複数の統計分析を同時に行う必要がよくあります。agg()関数はこのプロセスを簡潔かつ効率的にすることができます。


基本構文とパラメータ

agg()GroupBy オブジェクトのメンバー関数であり、先に使用する必要があります。groupby()グループ化してから呼び出します。

構文形式

GroupBy.agg(func=None, axis=0, *args, engine=None, engine_kwargs=None, **kwargs)

パラメータの説明

パラメータ 型 説明 デフォルト値
func str、list、dict または callable 集約関数。単一の関数名、関数のリスト、各列に異なる関数を指定する辞書を指定できます。 None
axis int 集約を適用する軸方向。0 は行方向(グループ化の次元)、1 は列方向を表します。 0
args tuple 集約関数に渡す追加の位置パラメータ。 ()
engine str 計算エンジンを指定します。'cython' または 'numba' を指定できます。None の場合は Pandas が自動的に選択します。 None
engine_kwargs dict 基盤となるエンジンに渡す追加パラメータの辞書。 None

戻り値

  • 戻り値の型:Series 或 DataFrame
  • 説明: グループ化および集約後の結果を返します。結果の構造は、func パラメータとグループ化の方法によって異なります。

例

簡単なものから複雑なものまでの一連の例を通して、徹底的に習得しましょう。groupby.agg()の使い方。

例1: 組み込み集約関数を使用

最も簡単な方法は、'sum'、'mean'、'max'、'min'、'count' などの Pandas 組み込みの集約関数名を直接使用することです。

例

import pandas as pd

# 販売データの DataFrame を作成
data = {
    '地域': ['華北', '華東', '華南', '華北', '華東', '華南', '華北', '華東'],
    '製品': ['A', 'B', 'C', 'B', 'A', 'C', 'A', 'B'],
    '売上高': [1000, 2000, 1500, 1800, 2200, 1600, 1200, 2100],
    '数量': [10, 20, 15, 18, 22, 16, 12, 21]
}
df = pd.DataFrame(data)

print("元の販売データ:")
print(df)
print()

# 「地域」でグループ化し、「売上高」列に複数の集約関数を同時に適用
# 文字列リストを使用して複数の集約関数を指定
result = df.groupby('地域')['売上高'].agg(['sum', 'mean', 'max', 'min', 'count'])

print("各地域の売上高の集計統計:")
print(result)
print()

# 「売上高」と「数量」の列を同時に集約
result_all = df.groupby('地域').agg({
    '売上高': ['sum', 'mean'],
    '数量': ['sum', 'mean']
})

print("各地域の売上と数量の総合統計:")
print(result_all)

実行結果:

原始销售数据:
  地区  产品   销售额   数量
0  华北   A   1000    10
1  华东   B   2000    20
2  华南   C   1500    15
3  华北   B   1800    18
4  华东   A   2200    22
5  华南   C   1600    16
6  华北   A   1200    12
7  华东   B   2100    21

每个地区销售额的汇总统计:
        sum    mean   max   min  count
地区
华东  7100  1775.0  2200  2000      4
华南  3100  1550.0  1600  1500      2
华北  4000  1333.333333  1800  1000      3

各地区销售和数量的综合统计:
              销售额         数量
              sum    mean  sum   mean
地区
华东  7100  1775.0   83  20.75
华南  3100  1550.0   31  15.50
华北  4000  1333.333333   40  13.33

コードの解説:

  1. ['sum', 'mean', 'max', 'min', 'count']リストを使用すると、複数の集約関数を同時に指定できます。
  2. 返される結果は DataFrame で、列名は関数名と元の列名で構成されます(マルチレベル列インデックス)。
  3. 辞書を使用すると、列ごとに異なる集約関数を指定できます。

例2: カスタム集約関数を使用

組み込み関数に加えて、agg()カスタム関数もサポートしており、柔軟性が大幅に拡張されます。

例

import pandas as pd
import numpy as np

# 学生の成績データを作成
data = {
    'クラス': ['A', 'A', 'A', 'B', 'B', 'B', 'B', 'A'],
    '名前': ['張三', '李四', '王五', '趙六', '孫七', '周八', '呉九', '鄭十'],
    '国語': [85, 92, 78, 88, 95, 82, 90, 87],
    '数学': [90, 85, 92, 78, 88, 91, 85, 89]
}
df = pd.DataFrame(data)

print("学生の成績データ:")
print(df)
print()

# カスタム集約関数を定義
def range_func(x):
    """最大値と最小値の差(範囲)を計算"""
    return x.max() - x.min()

def coefficient_of_variation(x):
    """変動係数(標準偏差/平均)を計算"""
    return x.std() / x.mean() * 100

# カスタム関数を使用して集約
# 関数名(文字列)または関数オブジェクトを直接渡すことができます
result = df.groupby('クラス').agg({
    '国語': ['sum', 'mean', range_func],  # 国語:合計、平均、範囲
    '数学': ['sum', 'mean', coefficient_of_variation]  # 数学:合計、平均、変動係数
})

print("各クラスのカスタム統計:")
print(result)
print()

# リスト内でカスタム関数を直接使用することもできます
result2 = df.groupby('クラス')['数学'].agg(['mean', range_func, 'std'])
print("各クラスの数学成績の統計(カスタム範囲と標準偏差を含む):")
print(result2)

実行結果:

学生成绩数据:
   班级  姓名  语文  数学
0  A   张三   85   90
1  A   李四   92   85
2  A   王五   78   92
3  B   赵六   88   78
4  B   孙七   95   88
5  B   周八   82   91
6  B   吴九   90   85
7  A   郑十   87   89

各班级的自定义统计:
               语文                 数学
              sum   mean range_func  sum    mean coefficient_of_variation
班级
A    342  85.5  14.0  425   88.25  5.019099

B    355  88.75  12.0  342   85.5  7.030

各班级数学成绩的统计(包含自定义极差和统计):
班级
A    88.25  5.0  2.692582
B    85.50  13.0  6.0

コードの解説:

  • カスタム関数は Series をパラメータとして受け取り、スカラー値を返します。
  • 関数名は文字列として渡すことができます(例:'sum')、または関数オブジェクトを直接渡すこともできます。
  • カスタム関数を使用すると、任意の複雑な集約ロジックを実装できます。

例3: 文字列エイリアスとラムダ関数を使用

agg()ラムダ式や組み込みの文字列エイリアスなど、複数の関数指定方法をサポートしています。

例

import pandas as pd

# 従業員の給与データを作成
data = {
    '部署': ['営業', '営業', '技術', '技術', '総務', '総務', '営業', '技術'],
    '役職': ['担当', 'マネージャー', '担当', 'マネージャー', '担当', 'マネージャー', '担当', 'マネージャー'],
    '給与': [5000, 8000, 7000, 12000, 4500, 9000, 5500, 11000],
    '勤続年数': [2, 5, 3, 8, 1, 6, 2, 7]
}
df = pd.DataFrame(data)

print(従業員の給与データ:)
print(df)
print()

# ラムダ関数を使用して柔軟なカスタム計算を実行
# 各部門の給与の中央値と平均値の差を計算
result = df.groupby('部署').agg({
    '給与': [
        ('平均給与', 'mean'),  # 集約結果にエイリアスを付ける
        ('最高給与', 'max'),
        ('最低給与', 'min'),
        ('給与範囲', lambda x: x.max() - x.min())
    ],
    '勤続年数': [
        ('平均勤続年数', 'mean'),
        ('最高勤続年数', 'max'),
        ('最低勤続年数', 'min')
    ]
})

print("各部門の給与と勤続年数の総合統計:")
print(result)
print()

# agg の短縮形を使用
result2 = df.groupby('部署')['給与'].agg(
平均='mean',
合計='sum',
人数='count'
)

print("名前付きパラメータ形式の集約結果:")
print(result2)

実行結果:

员工工资数据:
  部门   岗位    工资   工龄
0  销售   专员  5000    2
1  销售   经理  8000    5
2  技术   专员  7000    3
3  技术   经理  12000   8
4  行政   专员  4500    1
5  行政   经理  9000    6
6  销售   专员  5500    2
7  技术   经理  11000   7

各部门工资和工龄的综合统计:
                   工资                    工龄
            平均工资  最高工资  最低工资  工资极差  平均工龄  最高工龄  最低工龄
部门
技术   10000.0  12000   7000   5000   6.0    8    3
行政   6750.0   9000    4500   4500   3.5    6    1
销售   6166.666667  8000    5000   3000   3.0    5    1

使用命名参数形式的聚合结果:
          平均     总和   人数
部门
技术    10000.0  30000   3
行政     6750.0  13500   2
销售   6166.666667  18500   3

コードの解説:

  • タプルを使用すると、('別名', '関数名')集約結果の列にカスタム名を指定できます。
  • ラムダ式は直接agg()内で使用でき、簡単なカスタムロジックを実装できます。
  • 名前付きパラメータ形式(キーワードパラメータ)を使用すると、結果の列により直感的に名前を指定できます。

例4: 複数列でグループ化し、agg を使用

agg()複数列でのグループ化と組み合わせて使用することもでき、より複雑なデータ分析のニーズに対応できます。

例

import pandas as pd

# 販売データを作成
data = {
    '地域': ['華北', '華東', '華南', '華北', '華東', '華南', '華北', '華東', '華南'],
    '製品': ['A', 'B', 'C', 'B', 'A', 'C', 'A', 'B', 'C'],
    '売上高': [1000, 2000, 1500, 1800, 2200, 1600, 1200, 2100, 1700],
    '利益': [200, 400, 300, 360, 440, 320, 240, 420, 340]
}
df = pd.DataFrame(data)

print("売上データ:")
print(df)
print()

# 地域と製品でグループ化し、売上高と利益に対して複数の集計を行う
result = df.groupby(['地域', '製品']).agg({
    '売上高': ['sum', 'mean', 'count'],
    '利益': ['sum', 'mean']
})

print("地域と製品でグループ化した後の集計結果:")
print(result)
print()

# reset_index を使用して通常の DataFrame 形式に変換する
result_flat = df.groupby(['地域', '製品'], as_index=False).agg({
    '売上高': ['sum', 'mean'],
    '利益': ['sum', 'mean']
})

# 複数層の列インデックスをフラット化する
result_flat.columns = ['_'.join(col).strip('_') for col in result_flat.columns.values]

print("フラット化後の結果:")
print(result_flat)

実行結果:

销售数据:
 地区  产品   销售额   利润
0  华北   A   1000  200
1  华东   B   2000  400
2  华南   C   1500  300
3  华北   B   1800  360
4  华东   A   2200  440
5  华南   C   1600  320
6  华北   A   1200  240
7  华东   B   2100  420
9  华南   C    1700  340

按地区和产品分组后的聚合结果:
              销售额            利润
               sum  mean count   sum  mean
地区 产品
华东 A   2200  2200.0     1  440  440.0
     B   4100  2050.0     2  4100  4100.0
华南 C   3100  1550.0     2  3100  1550.0
华北 A   2200  1100.0     2  440  220.0
     B   1800  1800.0     1  360  360.0

展平后的结果:
   地区  产品  销售额_sum  销售额_mean  利润_sum  利润_mean
0  华东   A        2200      2200.0       440       440.0
1  华东   B        4100   2050.0      820       410.0
2  华南   C        3100   1550.0      660       330.0
3  华北   A        2200   1100.0      440       220.0
4  华北   B        1800   1800.0      360       360.0

コード解説:

  • 複数列でのグループ化は多段インデックス(MultiIndex)を生成します。
  • 使用するとas_index=Falseグループ化列を通常の列として保持できます。
  • によりcolumnsリネームすることで、複数層の列インデックスを単層にフラット化できます。

ヒント:agg()はグループ集計で最もよく使われる関数の1つであり、複数の統計指標を一度に計算できるだけでなく、カスタム関数にも対応しており、柔軟性が非常に高いです。実際のプロジェクトでその様々な使い方をしっかり習得することをお勧めします。


Pandas よく使う関数

その他の拡張