Python案例如何用Pandas做数据分组报告

wen python案例 1

本文目录导读:

Python案例如何用Pandas做数据分组报告

  1. 基础数据准备
  2. 基础分组聚合
  3. 多级分组报告
  4. 分组排名和排序
  5. 分组条件统计
  6. 时间序列分组
  7. 综合报告生成
  8. 可视化分组结果
  9. 高级分组技巧
  10. 完整报告导出

我来介绍使用Pandas进行数据分组分析的几个经典案例:

基础数据准备

import pandas as pd
import numpy as np
# 创建示例数据
data = {
    '部门': ['销售部', '技术部', '销售部', '技术部', '市场部', 
             '销售部', '技术部', '市场部', '销售部', '市场部'],
    '姓名': ['张三', '李四', '王五', '赵六', '钱七', 
             '孙八', '周九', '吴十', '郑一', '陈二'],
    '性别': ['男', '女', '男', '男', '女', 
             '男', '女', '男', '女', '男'],
    '年龄': [28, 32, 35, 27, 30, 45, 38, 29, 42, 33],
    '薪资': [8000, 15000, 9000, 18000, 12000, 
             10000, 16000, 11000, 9500, 13000],
    '入职日期': ['2020-01-15', '2019-03-20', '2021-06-01', '2018-09-10', 
                '2020-12-01', '2017-04-05', '2019-08-15', '2021-03-01',
                '2018-11-20', '2020-07-10']
}
df = pd.DataFrame(data)
df['入职日期'] = pd.to_datetime(df['入职日期'])
print("原始数据:")
print(df)

基础分组聚合

# 按部门分组,计算统计量
print("各部门薪资统计:")
dept_stats = df.groupby('部门')['薪资'].agg(['count', 'mean', 'std', 'min', 'max'])
print(dept_stats)
print()
# 多重聚合
print("\n各部门详细统计:")
detailed_stats = df.groupby('部门').agg({
    '薪资': ['mean', 'median', 'sum'],
    '年龄': ['mean', 'min', 'max'],
    '姓名': 'count'
})
print(detailed_stats)

多级分组报告

# 按部门和性别分组
print("按部门和性别分组统计:")
grouped = df.groupby(['部门', '性别']).agg({
    '薪资': ['mean', 'sum'],
    '年龄': 'mean',
    '姓名': 'count'
}).rename(columns={'姓名': '人数'})
print(grouped)
print()
# 添加总计行
print("\n包含总计的报表:")
pivot_table = df.pivot_table(
    values='薪资',
    index='部门',
    columns='性别',
    aggfunc=['mean', 'count'],
    margins=True,
    margins_name='总计'
)
print(pivot_table)

分组排名和排序

# 各部门薪资排名
df['部门内排名'] = df.groupby('部门')['薪资'].rank(ascending=False)
print("各部门薪资排名:")
print(df[['部门', '姓名', '薪资', '部门内排名']].sort_values(['部门', '部门内排名']))
print()
# 各部门前N名
top_2_by_dept = df.groupby('部门').apply(
    lambda x: x.nlargest(2, '薪资')
).reset_index(drop=True)
print("各部门薪资前2名:")
print(top_2_by_dept[['部门', '姓名', '薪资']])

分组条件统计

# 薪资高于平均的员工比例
dept_avg = df.groupby('部门')['薪资'].transform('mean')
df['是否高于平均'] = df['薪资'] > dept_avg
print("各部门高薪比例:")
high_ratio = df.groupby('部门')['是否高于平均'].mean()
print(high_ratio)
print()
# 年龄分组统计
age_bins = [20, 30, 40, 50]
age_labels = ['20-30岁', '30-40岁', '40-50岁']
df['年龄组'] = pd.cut(df['年龄'], bins=age_bins, labels=age_labels)
print("各年龄段薪资统计:")
age_group_stats = df.groupby('年龄组')['薪资'].describe()
print(age_group_stats)

时间序列分组

# 按入职年份分组
df['入职年份'] = df['入职日期'].dt.year
print("各年份入职员工薪资统计:")
yearly_stats = df.groupby('入职年份').agg({
    '薪资': ['mean', 'sum'],
    '姓名': 'count'
}).rename(columns={'姓名': '人数'})
print(yearly_stats)
print()
# 累计统计
cumulative_stats = df.sort_values('入职日期').groupby('部门')['薪资'].expanding().mean()
print("各部门薪资累积平均值:")
print(cumulative_stats)

综合报告生成

def generate_dept_report(df):
    """生成部门综合报告"""
    report = {
        '基础统计': df.groupby('部门').agg({
            '薪资': ['mean', 'median', 'std'],
            '年龄': ['mean', 'min', 'max'],
            '姓名': 'count'
        }).round(2),
        '性别分布': pd.crosstab(df['部门'], df['性别'], margins=True)
                    .rename(columns={'margins': '总计'}, index={'margins': '总计'}),
        '薪资区间': pd.cut(df['薪资'], bins=[0, 10000, 15000, 20000], 
                         labels=['低薪', '中薪', '高薪']).groupby(df['部门']).value_counts()
                    .unstack(fill_value=0)
    }
    return report
# 生成报告
dept_report = generate_dept_report(df)
print("=== 部门综合报告 ===")
print("\n1. 基础统计:")
print(dept_report['基础统计'])
print("\n2. 性别分布:")
print(dept_report['性别分布'])
print("\n3. 薪资区间分布:")
print(dept_report['薪资区间'])

可视化分组结果

import matplotlib.pyplot as plt
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 创建分组统计图表
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# 各部门平均薪资
df.groupby('部门')['薪资'].mean().plot(kind='bar', ax=axes[0, 0])
axes[0, 0].set_title('各部门平均薪资')
axes[0, 0].set_ylabel('薪资')
# 各部门人数分布
df['部门'].value_counts().plot(kind='pie', ax=axes[0, 1], autopct='%1.1f%%')
axes[0, 1].set_title('各部门人数占比')
# 薪资分布箱线图
df.boxplot(column='薪资', by='部门', ax=axes[1, 0])
axes[1, 0].set_title('各部门薪资分布')
axes[1, 0].set_ylabel('薪资')
# 年龄分布
df.groupby('部门')['年龄'].mean().plot(kind='line', marker='o', ax=axes[1, 1])
axes[1, 1].set_title('各部门平均年龄')
axes[1, 1].set_ylabel('年龄')
plt.tight_layout()
plt.show()

高级分组技巧

# 自定义分组函数
def salary_level(amount):
    if amount < 10000:
        return '低'
    elif amount < 15000:
        return '中'
    else:
        return '高'
df['薪资等级'] = df['薪资'].apply(salary_level)
print("薪资等级分布:")
grade_stats = df.groupby(['部门', '薪资等级']).size().unstack(fill_value=0)
print(grade_stats)
print()
# 分组后应用自定义函数
print("各部门薪资分级统计:")
dept_grade_stats = df.groupby('部门')['薪资'].agg([
    ('平均值', 'mean'),
    ('中位数', 'median'),
    ('高薪人数', lambda x: (x > 15000).sum()),
    ('低薪人数', lambda x: (x < 10000).sum())
]).round(2)
print(dept_grade_stats)

完整报告导出

def export_dept_report_to_excel(df, filename='部门报告.xlsx'):
    """导出部门报告到Excel"""
    with pd.ExcelWriter(filename, engine='openpyxl') as writer:
        # 各部门汇总
        summary = df.groupby('部门').agg({
            '薪资': ['mean', 'sum', 'count'],
            '年龄': 'mean'
        }).round(2)
        summary.to_excel(writer, sheet_name='汇总')
        # 详细信息
        details = df.sort_values(['部门', '薪资'], ascending=[True, False])
        details.to_excel(writer, sheet_name='详细数据', index=False)
        # 交叉分析
        cross = pd.crosstab(df['部门'], df['性别'], margins=True)
        cross.to_excel(writer, sheet_name='交叉分析')
        # 薪资分布
        salary_dist = df.groupby(['部门', pd.cut(df['薪资'], 
                                                   bins=3, 
                                                   labels=['低', '中', '高'])]).size().unstack()
        salary_dist.to_excel(writer, sheet_name='薪资分布')
    print(f"报告已导出到:{filename}")
# 导出报告
export_dept_report_to_excel(df)

这些案例涵盖了Pandas数据分组报告的常见应用场景,包括:

  • 基础分组统计
  • 多级分组
  • 分组排名
  • 条件统计
  • 时间序列分析
  • 综合报告生成
  • 可视化
  • 自定义分组
  • 报告导出

根据实际需求,可以组合使用这些技术来生成复杂的分析报告。

抱歉,评论功能暂时关闭!