本文目录导读:

我来为您详细介绍Pandas数据分组的常用方法,通过具体案例讲解。
基础分组案例
准备数据
import pandas as pd
import numpy as np
# 创建示例数据
df = pd.DataFrame({
'部门': ['技术部', '市场部', '技术部', '市场部', '技术部', '人事部', '人事部'],
'姓名': ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九'],
'年龄': [25, 30, 28, 35, 32, 27, 29],
'薪资': [15000, 12000, 18000, 11000, 16000, 9000, 10000],
'绩效': [85, 92, 78, 88, 95, 70, 82]
})
print("原始数据:")
print(df)
单列分组统计
# 按部门分组,计算平均薪资
result1 = df.groupby('部门')['薪资'].mean()
print("各部门平均薪资:")
print(result1)
# 按部门分组,计算多个统计量
result2 = df.groupby('部门').agg({
'薪资': ['mean', 'max', 'min'],
'年龄': 'mean',
'绩效': 'mean'
})
print("\n多维度统计:")
print(result2)
多列分组
# 添加城市列
df['城市'] = ['北京', '上海', '北京', '上海', '北京', '上海', '北京']
# 按部门和城市分组
result3 = df.groupby(['部门', '城市'])['薪资'].mean()
print("各部门各城市平均薪资:")
print(result3)
# 分组后重置索引
result4 = df.groupby(['部门', '城市'])['薪资'].mean().reset_index()
print("\n重置索引后的结果:")
print(result4)
实际应用案例
案例1:销售数据分析
# 创建销售数据
sales_data = pd.DataFrame({
'日期': pd.date_range('2024-01-01', periods=100, freq='D'),
'产品': np.random.choice(['A', 'B', 'C'], 100),
'地区': np.random.choice(['华北', '华东', '华南'], 100),
'销售额': np.random.randint(1000, 10000, 100),
'数量': np.random.randint(10, 100, 100)
})
# 按产品和地区统计月度销售
sales_data['月份'] = sales_data['日期'].dt.month
monthly_sales = sales_data.groupby(['月份', '产品', '地区']).agg({
'销售额': 'sum',
'数量': 'sum'
}).reset_index()
print("月度销售统计:")
print(monthly_sales.head())
案例2:学生成绩分析
# 创建学生成绩数据
students = pd.DataFrame({
'班级': np.repeat(['一班', '二班', '三班'], 10),
'学生': [f'学生{i}' for i in range(30)],
'语文': np.random.randint(60, 100, 30),
'数学': np.random.randint(60, 100, 30),
'英语': np.random.randint(60, 100, 30)
})
# 计算每个学生的总分
students['总分'] = students[['语文', '数学', '英语']].sum(axis=1)
# 按班级分组分析
class_analysis = students.groupby('班级').agg({
'总分': ['mean', 'max', 'min', 'std'],
'学生': 'count'
})
print("班级成绩分析:")
print(class_analysis)
# 找出每个班级的最高分
top_students = students.loc[students.groupby('班级')['总分'].idxmax()]
print("\n各班第一名:")
print(top_students[['班级', '学生', '总分']])
案例3:复杂聚合操作
# 使用apply进行自定义聚合
def score_range(x):
return x.max() - x.min()
# 按班级应用自定义函数
custom_agg = students.groupby('班级').agg({
'语文': ['mean', score_range],
'数学': ['mean', score_range],
'英语': ['mean', score_range]
})
print("自定义聚合结果:")
print(custom_agg)
# 多个聚合函数同时使用
multi_agg = students.groupby('班级').agg(
平均分=('总分', 'mean'),
最高分=('总分', 'max'),
最低分=('总分', 'min'),
人数=('学生', 'count')
)
print("\n清晰的分组统计:")
print(multi_agg)
高级分组技巧
1 分组后转换
# 计算每个学生相对于班级平均分的差距
students['相对于班级平均分'] = students.groupby('班级')['总分'].transform(lambda x: x - x.mean())
print("相对成绩:")
print(students[['班级', '学生', '总分', '相对于班级平均分']].head())
2 条件分组
# 根据条件创建分组
students['成绩等级'] = pd.cut(students['总分'],
bins=[0, 200, 250, 300],
labels=['不合格', '合格', '优秀'])
# 按成绩等级统计
grade_stats = students.groupby(['班级', '成绩等级']).size().unstack(fill_value=0)
print("各班级成绩等级分布:")
print(grade_stats)
3 分组后筛选
# 筛选出总分大于班级平均分的学生
above_avg = students[students.groupby('班级')['总分'].transform(lambda x: x > x.mean())]
print("超过班级平均分的学生:")
print(above_avg[['班级', '学生', '总分']])
实用技巧
# 1. 查看分组对象
grouped = df.groupby('部门')
print("分组对象:", grouped)
print("分组数量:", grouped.ngroups)
# 2. 遍历分组
for name, group in grouped:
print(f"\n{name}:")
print(group[['姓名', '薪资']])
# 3. 使用多个聚合函数
from pandas import NamedAgg
result = df.groupby('部门').agg(
平均薪资=NamedAgg(column='薪资', aggfunc='mean'),
最高薪资=NamedAgg(column='薪资', aggfunc='max'),
人数=NamedAgg(column='姓名', aggfunc='count')
)
print("\n使用NamedAgg的统计:")
print(result)
性能优化建议
# 大数据集时使用更高效的方法
# 1. 先过滤再分组
filtered_df = df[df['年龄'] > 25]
result = filtered_df.groupby('部门')['薪资'].mean()
# 2. 使用category数据类型
df['部门'] = df['部门'].astype('category')
df['城市'] = df['城市'].astype('category')
# 3. 避免循环,使用向量化操作
large_df = pd.DataFrame({
'group': np.random.choice(list('ABCD'), 1000000),
'value': np.random.randn(1000000)
})
result = large_df.groupby('group')['value'].describe()
这些案例覆盖了Pandas数据分组的主要应用场景,根据您的具体需求,可以灵活组合使用这些方法,记得在处理实际数据时注意数据类型和缺失值处理。