Python案例如何用Pandas做数据分组伸缩

wen python案例 2

本文目录导读:

Python案例如何用Pandas做数据分组伸缩

  1. 基础数据准备
  2. 基础分组操作
  3. 常见聚合函数用法
  4. 数据伸缩(变换)操作
  5. 高级分组操作
  6. 实际应用案例
  7. 性能优化技巧

我来详细介绍Pandas数据分组伸缩的常见案例和操作方法。

基础数据准备

import pandas as pd
import numpy as np
# 创建示例数据
df = pd.DataFrame({
    '部门': ['销售部', '销售部', '技术部', '技术部', '市场部', '市场部'],
    '区域': ['华东', '华北', '华东', '华北', '华东', '华北'],
    '销售员': ['张三', '李四', '王五', '赵六', '钱七', '孙八'],
    '销售额': [10000, 15000, 12000, 18000, 9000, 11000],
    '数量': [50, 75, 60, 90, 45, 55],
    '日期': ['2024-01', '2024-01', '2024-02', '2024-02', '2024-01', '2024-02']
})
print("原始数据:")
print(df)

基础分组操作

单列分组聚合

# 按部门分组,计算销售额总和
dept_sales = df.groupby('部门')['销售额'].sum()
print("各部门销售总额:")
print(dept_sales)
# 按部门分组,多列聚合
dept_stats = df.groupby('部门').agg({
    '销售额': ['sum', 'mean', 'max', 'min'],
    '数量': ['sum', 'mean']
})
print("\n各部门统计:")
print(dept_stats)

多列分组

# 按部门和区域分组
dept_region = df.groupby(['部门', '区域'])['销售额'].sum()
print("各部门各区域销售额:")
print(dept_region)

常见聚合函数用法

# 多种聚合方式
result = df.groupby('部门').agg(
    总销售额=('销售额', 'sum'),
    平均销售额=('销售额', 'mean'),
    最大销售额=('销售额', 'max'),
    销售次数=('销售额', 'count'),
    销售员列表=('销售员', lambda x: ', '.join(x))
)
print("综合统计:")
print(result)

数据伸缩(变换)操作

transform(保持原行数)

# 计算每个部门销售额占比
df['部门销售额占比'] = df.groupby('部门')['销售额'].transform(
    lambda x: x / x.sum() * 100
)
# 计算每个部门内的排名
df['部门内排名'] = df.groupby('部门')['销售额'].rank(ascending=False)
print("添加计算列后的数据:")
print(df[['部门', '销售员', '销售额', '部门销售额占比', '部门内排名']])

标准化处理

# Z-score标准化(按组)
df['销售额_zscore'] = df.groupby('部门')['销售额'].transform(
    lambda x: (x - x.mean()) / x.std()
)
# Min-Max标准化(按组)
df['销售额_minmax'] = df.groupby('部门')['销售额'].transform(
    lambda x: (x - x.min()) / (x.max() - x.min())
)
print("标准化后的数据:")
print(df[['部门', '销售员', '销售额', '销售额_zscore', '销售额_minmax']])

高级分组操作

自定义聚合函数

def custom_agg(x):
    """自定义聚合函数"""
    return {
        '数量': x.sum(),
        'avg_price': (x['销售额'].sum() / x['数量'].sum()).round(2),
        'top_seller': x.loc[x['销售额'].idxmax(), '销售员']
    }
# 应用自定义函数
result = df.groupby('部门').apply(custom_agg)
print("自定义聚合结果:")
print(result)

分组后的过滤

# 找出销售额大于平均水平的记录
above_avg = df.groupby('部门').filter(
    lambda x: x['销售额'].mean() > 13000
)
print("高于平均水平的记录:")
print(above_avg)
# 保留销售额最高的前2条记录
top2 = df.groupby('部门').apply(
    lambda x: x.nlargest(2, '销售额')
).reset_index(drop=True)
print("\n各部门Top2销售记录:")
print(top2)

实际应用案例

销售数据分析

# 创建更完整的销售数据
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(500, 5000, 100)
})
# 月度销售汇总
sales_data['月份'] = sales_data['日期'].dt.month
monthly_summary = sales_data.groupby(['月份', '产品']).agg(
    总销售额=('销售额', 'sum'),
    总成本=('成本', 'sum'),
    销售次数=('销售额', 'count'),
    平均利润率=('销售额', lambda x: ((x.sum() - sales_data.loc[x.index, '成本'].sum()) / x.sum() * 100).round(2))
).reset_index()
print("月度销售汇总:")
print(monthly_summary)
# 按区域和产品计算占比
sales_data['区域销售占比'] = sales_data.groupby('区域')['销售额'].transform(
    lambda x: x / x.sum() * 100
)
# 动态滚动统计(组内)
sales_data['区域累计销售额'] = sales_data.groupby('区域')['销售额'].transform(
    lambda x: x.expanding().sum()
)

薪资数据分析

# 员工薪资数据
salary_df = pd.DataFrame({
    '部门': ['技术']*6 + ['销售']*6 + ['人事']*6,
    '职级': ['初级', '中级', '高级']*6,
    '薪资': np.random.randint(5000, 30000, 18)
})
# 各部门薪资统计
salary_stats = salary_df.groupby(['部门', '职级']).agg(
    平均薪资=('薪资', 'mean'),
    最高薪资=('薪资', 'max'),
    最低薪资=('薪资', 'min'),
    薪资中位数=('薪资', 'median')
).round(0)
# 添加部门排名
salary_df['部门薪资排名'] = salary_df.groupby('部门')['薪资'].rank(ascending=False)
# 计算薪资与部门平均的差距
salary_df['与部门平均差距'] = salary_df['薪资'] - salary_df.groupby('部门')['薪资'].transform('mean')
print("薪资分析结果:")
print(salary_stats)
print("\n详细薪资数据:")
print(salary_df)

性能优化技巧

import time
# 大数据集测试
large_df = pd.DataFrame({
    'group': np.random.choice(list('ABCDE'), 100000),
    'value': np.random.randn(100000)
})
# 方法1:直接groupby
start = time.time()
result1 = large_df.groupby('group')['value'].sum()
print(f"直接groupby耗时: {time.time() - start:.4f}秒")
# 方法2:使用categorical类型优化
large_df['group'] = large_df['group'].astype('category')
start = time.time()
result2 = large_df.groupby('group', observed=True)['value'].sum()
print(f"优化后耗时: {time.time() - start:.4f}秒")
# 方法3:多个聚合同时进行
start = time.time()
result3 = large_df.groupby('group')['value'].agg(['sum', 'mean', 'std'])
print(f"多聚合耗时: {time.time() - start:.4f}秒")
# 1. 重置索引
result = df.groupby('部门')['销售额'].sum().reset_index()
# 2. 多重索引处理
result = df.groupby(['部门', '区域'])['销售额'].sum().unstack()
# 3. 条件分组
df['业绩等级'] = pd.cut(df['销售额'], 
    bins=[0, 10000, 15000, float('inf')],
    labels=['低', '中', '高']
)
# 4. 分组后合并
group_keys = list(df.groupby('部门').groups.keys())
# 5. 自定义分组键
df['分组'] = df.apply(
    lambda row: '高绩效' if row['销售额'] > row['数量'] * 200 else '普通',
    axis=1
)

这些案例涵盖了Pandas分组伸缩的常用操作,从基础到高级应用都有涉及,根据实际需求,你可以灵活组合这些方法来解决数据分析中的各种问题。

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