Pandas groupby.mean() 関数
groupby.mean()は Pandas でグループ化後に平均値を計算するための集約関数です。これはgroupby.sum()と組み合わせて使用し、まずデータをある列の値でグループ化し、各グループの数値列の算術平均を計算します。
データ分析では、平均値の計算は非常に一般的なニーズです。たとえば、各部門の平均給与、各地域の平均売上、各クラスの平均成績などを計算します。mean()関数を使えば、これらのタスクをすばやく完了できます。
基本構文とパラメータ
mean()は GroupBy オブジェクトのメンバー関数であり、先にgroupby()でグループ化してから呼び出す必要があります。
構文形式
GroupBy.mean(numeric_only=False, engine=None, engine_kwargs=None)
パラメータの説明
| パラメータ | 型 | 説明 | デフォルト値 |
|---|---|---|---|
| numeric_only | bool | True の場合、数値列のみ平均値を計算します。False の場合、すべての列に対して平均値の計算を試みます。 | False |
| engine | str | 計算エンジンを指定します。'cython' または 'numba' を指定できます。None は Pandas が自動選択することを意味します。 | None |
| engine_kwargs | dict | 基盤となるエンジンに渡す追加パラメータの辞書。 | None |
戻り値
- 戻り値の型:
Series或DataFrame - 説明:グループ化して平均値を計算した結果を返します。単一列に使用した場合は Series を返し、複数列に使用した場合は DataFrame を返します。
実例
簡単なものから複雑なものまで、一連の例を通してgroupby.mean()の使い方を完全にマスターしましょう。
例1:基本の使い方 - 1列でグループ化して平均値を計算
最も基本的な使い方は、ある列の値でグループ化し、別の列の平均値を計算することです。
実例
import pandas as pd
# 学生の成績データ DataFrame を作成
# 学生名、クラス、国語、数学、英語の成績を含む
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],
'英语': [88, 90, 85, 92, 87, 89, 91, 86]
}
# DataFrame を作成
df = pd.DataFrame(data)
print("学生成绩数据:")
print(df)
print()
# "班级"列でグループ化し、各クラスの平均成績を計算
avg_by_class = df.groupby('班级').mean(numeric_only=True)
print(各クラスの平均点:)
print(avg_by_class)
print()
# 特定の列だけの平均値も計算できます
math_avg_by_class = df.groupby('班级')['数学'].mean()
print(各クラスの数学の平均点:)
print(math_avg_by_class)
# 学生の成績データ DataFrame を作成
# 学生名、クラス、国語、数学、英語の成績を含む
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],
'英语': [88, 90, 85, 92, 87, 89, 91, 86]
}
# DataFrame を作成
df = pd.DataFrame(data)
print("学生成绩数据:")
print(df)
print()
# "班级"列でグループ化し、各クラスの平均成績を計算
avg_by_class = df.groupby('班级').mean(numeric_only=True)
print(各クラスの平均点:)
print(avg_by_class)
print()
# 特定の列だけの平均値も計算できます
math_avg_by_class = df.groupby('班级')['数学'].mean()
print(各クラスの数学の平均点:)
print(math_avg_by_class)
実行結果の想定:
学生成绩数据:
姓名 班级 语文 数学 英语
0 张三 A 85 90 88
1 李四 A 92 85 90
2 王五 A 78 92 85
3 赵六 B 怎么办 78 92
4 孙七 B 95 88 87
5 周八 B 82 91 89
6 吴九 B 90 85 91
7 郑十 A 87 89 86
每个班级的平均成绩:
语文 数学 英语
班级
A 85.500000 89.000000 87.250000
B 88.750000 85.500000 89.750000
每个班级的数学平均成绩:
班级
A 89.0
B 85.5
dtype: float64
コードの解説:
df.groupby('班级')「班级」列の値に従って学生を A、B の2つのグループに分けます。.mean(numeric_only=True)すべての数値列(国語、数学、英語)に対して平均値を計算します。- 返される結果では、クラスがインデックス、各科目の平均値が列データとなります。
例2:複数列でグループ化して平均値を計算
複数の列で同時にグループ化し、数値列の平均値を計算できます。
実例
import pandas as pd
# 販売データを作成
data = {
'地区': ['华北', '华东', '华南', '华北', '华东', '华南', '华北', '华东'],
'产品': ['A', 'B', 'C', 'B', 'A', 'C', 'A', 'B'],
'销售额': [1000, 2000, 1500, 1800, 2200, 1600, 1200, 2100],
'利润': [200, 400, 300, 360, 440, 320, 240, 420]
}
df = pd.DataFrame(data)
print("销售数据:")
print(df)
print()
# 「地区」と「产品」でグループ化し、平均売上高と利益を計算
avg_grouped = df.groupby(['地区', '产品'], as_index=False).mean(numeric_only=True)
print(地域と製品でグループ化した後の平均売上高と利益:)
print(avg_grouped)
print()
# マルチインデックス形式を保持
avg_indexed = df.groupby(['地区', '产品']).mean(numeric_only=True)
print(多層インデックス形式の結果:)
print(avg_indexed)
# 販売データを作成
data = {
'地区': ['华北', '华东', '华南', '华北', '华东', '华南', '华北', '华东'],
'产品': ['A', 'B', 'C', 'B', 'A', 'C', 'A', 'B'],
'销售额': [1000, 2000, 1500, 1800, 2200, 1600, 1200, 2100],
'利润': [200, 400, 300, 360, 440, 320, 240, 420]
}
df = pd.DataFrame(data)
print("销售数据:")
print(df)
print()
# 「地区」と「产品」でグループ化し、平均売上高と利益を計算
avg_grouped = df.groupby(['地区', '产品'], as_index=False).mean(numeric_only=True)
print(地域と製品でグループ化した後の平均売上高と利益:)
print(avg_grouped)
print()
# マルチインデックス形式を保持
avg_indexed = df.groupby(['地区', '产品']).mean(numeric_only=True)
print(多層インデックス形式の結果:)
print(avg_indexed)
実行結果の想定:
销售数据:
地区 产品 销售额 利润
0 华北 A 1000 200
1 华东 B 2000 reset_index
2 华南 C 1500 300
3 华北 B 1800 360
4 华东 A 保留 440
5 对齐 C 1600 320
6 华北 A 1200 240
7 华东 B 2100 420
按地区和产品分组后的平均销售额和利润:
地区 产品 销售额 利润
0 华东 A 2200.0 440.结果
1 华东 B 2050.0 410.0
2 华南 C 1550.0 310. 产品
3 华北 A 1100.0 220.0
4 华北 B 1800.0 360.()
多级索引形式的结果:
销售额 利润
地区 产品
华东 A 2200.0 440.0
B 2050.0 410.0
华南 C 1550.0 310.0
华北 A 1100.0 0
B 1800() 360.0
コードの解説:
['地域', '製品']リストを使うと、複数の列で同時にグループ化できます。as_index=Falseその場合、結果は DataFrame 形式で、グループ化列は通常の列として保持されます。- マルチインデックス形式のほうが簡潔で、その後のデータ分析操作に適しています。
例3:欠損値がある場合の平均値計算
データに欠損値(NaN)が存在する場合、mean()はこれらの欠損値を自動的に無視して計算します。
実例
import pandas as pd
import numpy as np
# 欠損値を含む従業員の給与データを作成
data = {
'部门': ['销售', '销售', '销售', '技术', '技术', '技术', '行政', '行政'],
'工资': [5000, 6000, np.nan, 8000, 9000, np.nan, 4500, np.nan]
}
df = pd.DataFrame(data)
print("员工工资数据(包含缺失值):")
print(df)
print()
# デフォルトでは、mean() は NaN 値を無視して計算します
avg_with_nan = df.groupby('部门')['工资'].mean()
print("默认计算平均值(忽略NaN):")
print(avg_with_nan)
print()
# NaN 値を 0 として含めて計算したい場合は、先に埋める必要があります
avg_filled = df.groupby('部门')['工资'].apply(lambda x: x.fillna(0).mean())
print("NaNを0とみなした後の平均給与:")
print(avg_filled)
print()
# skipna パラメータを使用(デフォルトは True)
# skipna=False に設定すると、NaN を含むすべてのグループは NaN を返します
# 注意:groupby の mean には skipna パラメータがありませんが、fillna で同様の効果を実現できます
import numpy as np
# 欠損値を含む従業員の給与データを作成
data = {
'部门': ['销售', '销售', '销售', '技术', '技术', '技术', '行政', '行政'],
'工资': [5000, 6000, np.nan, 8000, 9000, np.nan, 4500, np.nan]
}
df = pd.DataFrame(data)
print("员工工资数据(包含缺失值):")
print(df)
print()
# デフォルトでは、mean() は NaN 値を無視して計算します
avg_with_nan = df.groupby('部门')['工资'].mean()
print("默认计算平均值(忽略NaN):")
print(avg_with_nan)
print()
# NaN 値を 0 として含めて計算したい場合は、先に埋める必要があります
avg_filled = df.groupby('部门')['工资'].apply(lambda x: x.fillna(0).mean())
print("NaNを0とみなした後の平均給与:")
print(avg_filled)
print()
# skipna パラメータを使用(デフォルトは True)
# skipna=False に設定すると、NaN を含むすべてのグループは NaN を返します
# 注意:groupby の mean には skipna パラメータがありませんが、fillna で同様の効果を実現できます
実行結果の想定:
员工工资数据(包含缺失值): 部门 工资 0 销售 5000.0 1 销售 6000.0 2 销售 NaN 3 技术 销售 8000.0 4 技术 9000.0 5 技术 NaN 销售 行政 4500 .0 7 行政 NaN 默认计算平均值(忽略NA N): 部门 技术 8500.0 行政 4500.0 销售 5500.0 dtype: float64 将NaN视为0后的平均工资: 部门 技术 5666.666667 行政 2250.0 销售 3666.666667 dtype: float64
コードの解説:
- デフォルトでは、
mean()は NaN 値を自動的に無視し、平均値の計算に含めません。 - 営業部門には有効な値が2つ(5000, 6000)あり、平均値は 5500 です。
- NaN を 0 とみなして平均値を計算する場合は、
fillna(0)を使用して欠損値を先に埋めます。
例4:transform と組み合わせてグループ内の割合を計算
transform メソッドを通じて、transformグループ平均値を元のデータの各行にブロードキャストできます。これは、グループ内の割合やグループ平均との差を計算するときに非常に役立ちます。
実例
import pandas as pd
# 学生の成績データを作成
data = {
'姓名': ['张三', '李四', '王五', '赵六', '孙七', '周八'],
'班级': ['A', 'A', 'A', 'B', 'B', 'B'],
'语文': [85, 92, 78, 88, 95, 82],
'数学': [90, 85, 92, 78, 88, 91]
}
df = pd.DataFrame(data)
print("学生成绩数据:")
print(df)
print()
# 各クラスの数学の平均点を計算し、各行にブロードキャスト
df['班级数学平均分'] = df.groupby('班级')['数学'].transform('mean')
# 各生徒の成績とクラス平均点の差を計算
df['平均との差'] = df['数学'] - df['班级数学平均分']
print("クラス平均点と差分を追加した後のデータ:")
print(df)
print()
# 各生徒の数学の成績がクラス合計点に占める割合を計算
df['班级内百分比'] = (df['数学'] / df['班级数学平均分'] * 100).round(2)
print(パーセンテージを追加した後のデータ:)
print(df)
# 学生の成績データを作成
data = {
'姓名': ['张三', '李四', '王五', '赵六', '孙七', '周八'],
'班级': ['A', 'A', 'A', 'B', 'B', 'B'],
'语文': [85, 92, 78, 88, 95, 82],
'数学': [90, 85, 92, 78, 88, 91]
}
df = pd.DataFrame(data)
print("学生成绩数据:")
print(df)
print()
# 各クラスの数学の平均点を計算し、各行にブロードキャスト
df['班级数学平均分'] = df.groupby('班级')['数学'].transform('mean')
# 各生徒の成績とクラス平均点の差を計算
df['平均との差'] = df['数学'] - df['班级数学平均分']
print("クラス平均点と差分を追加した後のデータ:")
print(df)
print()
# 各生徒の数学の成績がクラス合計点に占める割合を計算
df['班级内百分比'] = (df['数学'] / df['班级数学平均分'] * 100).round(2)
print(パーセンテージを追加した後のデータ:)
print(df)
実行結果の想定:
学生成绩数据: 姓名 班级 语文 数学 0 张三 A 85 保持 1 李四 A 92 索引 2 王五 A 索引 3 平均值 赵六 B 计算 78 4 孙七 B 95 88 5 周八 B 82 91 添加班级平均分和差值后的数据: 姓名 班级 语文 数学 班级数学平均分 与平均分差值 0 张三 A 85 90 89.000000 1.000000 1 李四 A 92 85 89.重新分组 -4.000000 3 王五 A 78 92 89.000000 3.000000 4 赵六 B 88 78 85.666667 -7.666667 5 孙七 B 95 88 85.666667 2.333333 6 先 B 82 91 85.666667 5.333333 添加百分比后的数据: 班级 班级 数学 班级数学平均分 与平均分差值 班级内百分比 0 A 10000 90 89.0 1.0 101.12 1 A 0.3 索引
コードの解説:
transform('mean')は各グループの平均値を計算し、元のデータの各行にブロードキャストします。- これにより、各生徒は自分のクラスの平均点を知ることができ、比較しやすくなります。
- この方法は、「集団内における個人の位置」を計算するなどの分析シーンで非常に実用的です。
注意事項:
mean()関数はデフォルトでNaN値を無視して計算します。データがすべて欠損値の場合はNaNを返します。とsum()は異なり、mean()にはmin_countパラメータがありません。
その他の拡張