本文目录导读:

我来详细讲解如何使用Pandas进行数据分组透视,包含多个实用案例。
数据准备
import pandas as pd
import numpy as np
# 创建示例数据
data = {
'部门': ['技术部', '市场部', '技术部', '市场部', '技术部', '人事部', '市场部', '人事部', '技术部', '人事部'],
'性别': ['男', '女', '男', '女', '男', '女', '男', '女', '女', '男'],
'薪资': [15000, 12000, 18000, 11000, 20000, 9000, 13000, 8500, 16000, 9500],
'年龄': [28, 32, 35, 27, 30, 26, 33, 29, 31, 28],
'绩效评分': [85, 92, 78, 88, 95, 80, 85, 90, 82, 75],
'入职年份': [2020, 2019, 2018, 2021, 2020, 2021, 2019, 2020, 2021, 2020]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
基础分组操作
# 单列分组 - 按部门分组计算平均薪资
grouped_dept = df.groupby('部门')['薪资'].mean()
print("\n各部门平均薪资:")
print(grouped_dept)
# 多列分组
grouped_multi = df.groupby(['部门', '性别'])['薪资'].mean()
print("\n各部门各性别平均薪资:")
print(grouped_multi)
# 多个聚合函数
grouped_agg = df.groupby('部门')['薪资'].agg(['mean', 'sum', 'count', 'max', 'min'])
print("\n各部门薪资统计:")
print(grouped_agg)
多重聚合计算
# 对不同列使用不同聚合函数
agg_dict = {
'薪资': ['mean', 'sum', 'std'],
'年龄': ['mean', 'max', 'min'],
'绩效评分': ['mean', 'max']
}
grouped_multi_agg = df.groupby('部门').agg(agg_dict)
print("\n多重聚合统计:")
print(grouped_multi_agg)
# 使用命名聚合(Pandas 0.25+)
named_agg = df.groupby('部门').agg(
平均薪资=('薪资', 'mean'),
最高薪资=('薪资', 'max'),
平均年龄=('年龄', 'mean'),
平均绩效=('绩效评分', 'mean')
)
print("\n命名聚合结果:")
print(named_agg)
创建数据透视表
# 基础透视表 - 按部门和性别计算平均薪资
pivot_table1 = pd.pivot_table(
df,
values='薪资',
index='部门',
columns='性别',
aggfunc='mean'
)
print("\n基础透视表(平均薪资):")
print(pivot_table1)
# 多值透视表
pivot_table2 = pd.pivot_table(
df,
values=['薪资', '绩效评分'],
index='部门',
columns='性别',
aggfunc='mean'
)
print("\n多值透视表:")
print(pivot_table2)
# 带汇总的透视表
pivot_table3 = pd.pivot_table(
df,
values='薪资',
index='部门',
columns='性别',
aggfunc='mean',
margins=True, # 添加汇总行和列
margins_name='总计'
)
print("\n带汇总的透视表:")
print(pivot_table3)
高级分组操作
# 自定义聚合函数
def salary_range(x):
return x.max() - x.min()
custom_agg = df.groupby('部门')['薪资'].agg([
('均值', 'mean'),
('范围', salary_range),
('中位数', lambda x: x.median())
])
print("\n自定义聚合函数:")
print(custom_agg)
# 分组后转换(transform)
df['薪资百分比'] = df.groupby('部门')['薪资'].transform(lambda x: x / x.sum() * 100)
print("\n添加薪资百分比列:")
print(df[['部门', '薪资', '薪资百分比']])
# 分组后过滤
filtered = df.groupby('部门').filter(lambda x: x['薪资'].mean() > 12000)
print("\n平均薪资超过12000的部门数据:")
print(filtered)
实际业务案例
# 案例1:员工绩效分析
print("\n=== 员工绩效分析 ===")
performance_analysis = pd.pivot_table(
df,
values=['绩效评分', '薪资'],
index=['部门', '性别'],
aggfunc={
'绩效评分': ['mean', 'max', 'min'],
'薪资': ['mean', 'sum']
}
)
print(performance_analysis)
# 案例2:年度入职分析
df['入职年份'] = df['入职年份'].astype(str) # 转换为字符串便于分类
yearly_analysis = df.groupby(['入职年份', '部门']).agg(
员工数=('薪资', 'count'),
平均薪资=('薪资', 'mean'),
平均绩效=('绩效评分', 'mean')
)
print("\n=== 年度入职分析 ===")
print(yearly_analysis)
# 案例3:薪资等级分析
df['薪资等级'] = pd.cut(df['薪资'],
bins=[0, 10000, 15000, 20000, float('inf')],
labels=['低', '中', '高', '很高'])
grade_analysis = pd.pivot_table(
df,
values='员工姓名' if '员工姓名' in df.columns else '薪资',
index='部门',
columns='薪资等级',
aggfunc='count',
fill_value=0
)
print("\n=== 薪资等级分布 ===")
print(grade_analysis)
数据可视化配合
import matplotlib.pyplot as plt
# 准备可视化数据
dept_stats = df.groupby('部门').agg({
'薪资': 'mean',
'绩效评分': 'mean',
'年龄': 'mean'
}).round(1)
# 创建图表
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
# 平均薪资柱状图
dept_stats['薪资'].plot(kind='bar', ax=axes[0], title='各部门平均薪资')
axes[0].set_ylabel('薪资(元)')
# 平均绩效柱状图
dept_stats['绩效评分'].plot(kind='bar', ax=axes[1], title='各部门平均绩效')
axes[1].set_ylabel('绩效评分')
# 散点图
axes[2].scatter(dept_stats['薪资'], dept_stats['绩效评分'])
axes[2].set_xlabel('平均薪资')
axes[2].set_ylabel('平均绩效')
axes[2].set_title('薪资与绩效关系')
plt.tight_layout()
plt.show()
性能优化技巧
# 使用类别类型优化
df['部门'] = df['部门'].astype('category')
# 分组时指定排序
result = df.groupby('部门', sort=False)['薪资'].mean()
# 使用agg方法而不是多次groupby
# 不推荐:
# mean_salary = df.groupby('部门')['薪资'].mean()
# max_salary = df.groupby('部门')['薪资'].max()
# 推荐:
optimized = df.groupby('部门')['薪资'].agg(['mean', 'max', 'min'])
常见问题解决
# 处理缺失值
df_with_na = df.copy()
df_with_na.loc[0, '薪资'] = np.nan
# 分组时忽略缺失值
result_no_na = df_with_na.groupby('部门')['薪资'].mean()
print("\n忽略缺失值的分组结果:")
print(result_no_na)
# 保留缺失值信息
result_keep_na = df_with_na.groupby('部门', dropna=False)['薪资'].mean()
print("\n保留缺失值的分组结果:")
print(result_keep_na)
# 处理重复索引
df_duplicated = pd.concat([df, df.iloc[[0, 1]]])
result_dedup = df_duplicated.groupby('部门', as_index=False)['薪资'].mean()
print("\n去重后的分组结果:")
print(result_dedup)
Pandas数据分组透视的主要功能:
- groupby():基础分组,支持单列和多列分组
- pivot_table():创建数据透视表,更灵活的维度展示
- agg():应用多个聚合函数,支持自定义函数
- transform():保持原数据形状的转换操作
- filter():按条件过滤分组数据
这些功能在数据分析和报表生成中非常实用,可以高效处理各种统计需求。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播