本文目录导读:

我来详细讲解如何使用Pandas进行数据分组对比,包含多个实用案例。
基本数据准备
import pandas as pd
import numpy as np
# 创建示例数据
np.random.seed(42)
data = {
'部门': np.random.choice(['销售部', '技术部', '市场部', '财务部'], 100),
'性别': np.random.choice(['男', '女'], 100),
'年龄': np.random.randint(22, 55, 100),
'薪资': np.random.randint(5000, 30000, 100),
'绩效': np.random.randint(60, 100, 100),
'城市': np.random.choice(['北京', '上海', '广州', '深圳'], 100)
}
df = pd.DataFrame(data)
print("数据概览:")
print(df.head())
print(f"\n数据维度:{df.shape}")
单列分组统计
# 按部门分组,计算薪资均值
dept_salary = df.groupby('部门')['薪资'].mean()
print("各部门平均薪资:")
print(dept_salary)
# 按部门分组,多指标统计
dept_stats = df.groupby('部门').agg({
'薪资': ['mean', 'std', 'min', 'max'],
'年龄': 'mean',
'绩效': 'mean'
}).round(2)
print("\n各部门详细统计:")
print(dept_stats)
多维度分组对比
# 按部门和性别分组
grouped = df.groupby(['部门', '性别'])['薪资'].mean().unstack()
print("各部门不同性别平均薪资对比:")
print(grouped)
# 多维度多指标聚合
multi_group = df.groupby(['部门', '城市']).agg({
'薪资': ['mean', 'count'],
'绩效': 'mean',
'年龄': ['min', 'max']
}).round(2)
print("\n各部门各城市详细统计:")
print(multi_group)
分组后计算差异
# 计算各部门与总体均值的差异
overall_mean = df['薪资'].mean()
dept_diff = df.groupby('部门')['薪资'].mean() - overall_mean
print("各部门薪资与总体均值差异:")
print(dept_diff)
# 计算性别薪资差异
gender_diff = df.groupby('性别')['薪资'].mean()
salary_gap = gender_diff['男'] - gender_diff['女']
print(f"\n性别薪资差异:{salary_gap:.2f}元")
高级分组分析
# 自定义分组函数
def salary_level(salary):
if salary < 10000:
return '低薪'
elif salary < 20000:
return '中薪'
else:
return '高薪'
df['薪资等级'] = df['薪资'].apply(salary_level)
# 按薪资等级分组分析
level_analysis = df.groupby('薪资等级').agg({
'薪资': ['mean', 'count'],
'绩效': 'mean',
}).round(2)
print("薪资等级分析:")
print(level_analysis)
# 年龄分组
df['年龄组'] = pd.cut(df['年龄'], bins=[20, 30, 40, 50, 60], labels=['20-30', '30-40', '40-50', '50-60'])
age_analysis = df.groupby('年龄组')['薪资'].agg(['mean', 'count'])
print("\n年龄组薪资分析:")
print(age_analysis)
对比可视化
import matplotlib.pyplot as plt
import seaborn as sns
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# 1. 各部门薪资对比
dept_data = df.groupby('部门')['薪资'].mean().sort_values()
dept_data.plot(kind='bar', ax=axes[0, 0], color='skyblue')
axes[0, 0].set_title('各部门平均薪资对比')
axes[0, 0].set_ylabel('平均薪资(元)')
# 2. 部门+性别交叉对比
cross_data = df.groupby(['部门', '性别'])['薪资'].mean().unstack()
cross_data.plot(kind='bar', ax=axes[0, 1])
axes[0, 1].set_title('各部门不同性别薪资对比')
axes[0, 1].set_ylabel('平均薪资(元)')
axes[0, 1].legend(title='性别')
# 3. 分组箱线图
df.boxplot(column='薪资', by='部门', ax=axes[1, 0])
axes[1, 0].set_title('各部门薪资分布对比')
axes[1, 0].set_ylabel('薪资(元)')
# 4. 薪资等级分布
level_count = df.groupby(['薪资等级', '部门']).size().unstack(fill_value=0)
level_count.plot(kind='bar', stacked=True, ax=axes[1, 1])
axes[1, 1].set_title('各部门薪资等级分布')
axes[1, 1].set_ylabel('人数')
plt.tight_layout()
plt.show()
条件分组对比
# 筛选条件后分组
high_performer = df[df['绩效'] > 80]
performance_analysis = high_performer.groupby('部门').agg({
'薪资': 'mean',
'绩效': 'mean',
'性别': lambda x: x.value_counts().index[0] # 多数性别
}).round(2)
print("高绩效员工各部门分析:")
print(performance_analysis)
# 分组后过滤
dept_groups = df.groupby('部门').filter(lambda x: len(x) > 15)
print(f"\n过滤后数据维度:{dept_groups.shape}")
实用分析案例
# 案例1:薪资排名对比
dept_rank = df.groupby('部门')['薪资'].mean().rank(ascending=False)
print("部门薪资排名:")
print(dept_rank)
# 案例2:绩效等级分布
def performance_level(score):
if score >= 90:
return 'A'
elif score >= 80:
return 'B'
elif score >= 70:
return 'C'
else:
return 'D'
df['绩效等级'] = df['绩效'].apply(performance_level)
# 交叉分析
cross_table = pd.crosstab(df['部门'], df['绩效等级'], margins=True)
print("\n绩效等级交叉分析表:")
print(cross_table)
# 案例3:城市间对比
city_stats = df.groupby('城市').agg({
'薪资': 'mean',
'绩效': 'mean',
'年龄': 'mean'
}).round(2)
print("\n各城市指标对比:")
print(city_stats)
批量对比函数
def compare_groups(df, group_col, compare_col, metrics=['mean', 'std', 'min', 'max']):
"""
通用分组对比函数
"""
result = df.groupby(group_col)[compare_col].agg(metrics).round(2)
# 添加总体均值
overall = df[compare_col].mean()
result['总体均值'] = overall
# 计算差异百分比
for metric in metrics:
if metric == 'mean':
result['差异(%)'] = ((result[metric] - overall) / overall * 100).round(2)
return result
# 使用函数
result = compare_groups(df, '部门', '薪资')
print("各部门薪资对比分析:")
print(result)
这些案例涵盖了Pandas数据分组对比的常见场景,根据你的具体需求,可以调整分组字段、聚合函数和对比维度,关键点包括:
- 选择合适的分组维度:单列、多列、自定义函数
- 合理使用聚合函数:mean, sum, count, std等
- 注意数据清洗:处理缺失值、异常值
- 可视化辅助分析:图表能直观展示差异
需要我详细解释某个特定场景或功能吗?