Pandas groupby.agg() 関数
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)
# 販売データの 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
コードの解説:
['sum', 'mean', 'max', 'min', 'count']リストを使用すると、複数の集約関数を同時に指定できます。- 返される結果は DataFrame で、列名は関数名と元の列名で構成されます(マルチレベル列インデックス)。
- 辞書を使用すると、列ごとに異なる集約関数を指定できます。
例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)
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)
# 従業員の給与データを作成
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)
# 販売データを作成
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つであり、複数の統計指標を一度に計算できるだけでなく、カスタム関数にも対応しており、柔軟性が非常に高いです。実際のプロジェクトでその様々な使い方をしっかり習得することをお勧めします。
その他の拡張