Python案例如何用Pandas做数据索引展开

wen python案例 1

本文目录导读:

Python案例如何用Pandas做数据索引展开

  1. 📖 目录导读
  2. 为什么要展开数据索引?
  3. Pandas索引展开的三种核心方法
  4. 实战案例:电商订单数据索引展开
  5. 常见问题与SEO优化问答
  6. 索引展开的最佳实践

Python实战案例:如何用Pandas高效展开数据索引(附完整代码)

📖 目录导读

  1. 为什么要展开数据索引? —— 理解索引展开的核心场景
  2. Pandas索引展开的三种核心方法
    • stack()unstack() 重塑层级索引
    • melt() 实现宽表转长表(逆透视)
    • pivot()pivot_table() 展开行索引为列
  3. 实战案例:电商订单数据索引展开
    • 原始数据问题分析
    • 分步代码实现
  4. 常见问题与SEO优化问答
    • Q1: 索引展开后数据行数变化异常?
    • Q2: 多层索引如何只展开某一层?
  5. 索引展开的最佳实践

为什么要展开数据索引?

在数据清洗和特征工程中,经常遇到多层索引(MultiIndex)行索引包含多级分类信息的情况。

  • 时间序列数据:年份/月份作为行索引
  • 分组统计结果:城市/品类作为行索引
  • 宽表数据:每个行的列名本身带有类别信息

索引展开的核心目的: ✅ 将索引中的层级信息转换为列
✅ 为机器学习模型提供扁平化特征
✅ 满足可视化工具对宽表/长表的需求


Pandas索引展开的三种核心方法

stack()unstack() 重塑层级索引

# 模拟多级索引数据
import pandas as pd
data = {
    ('2023', 'Q1'): [100, 200],
    ('2023', 'Q2'): [150, 250],
    ('2024', 'Q1'): [180, 280]
}
df = pd.DataFrame(data, index=['产品A', '产品B'])
df.columns.names = ['年份', '季度']
  • unstack(level=1):将第二层级索引(季度)展开为列

    df.unstack(level=1)
    # 输出列名变为多级:(年份, 季度) → 扁平化为 年份_季度
  • stack():将列索引堆叠为行索引(逆操作)

melt() 实现宽表转长表(逆透视)

当列名本身是数据的一部分时(如月份列1月、2月),需要展开为键值对:

df_wide = pd.DataFrame({
    '城市': ['北京', '上海'],
    '1月': [100, 150],
    '2月': [200, 250]
})
df_long = df_wide.melt(id_vars=['城市'], 
                       var_name='月份', 
                       value_name='销售额')

pivot()pivot_table() 展开行索引为列

适用于将长表还原为宽表,或将某列的值展开为新列索引:

# 假设原数据:每条记录是某日某城市的销售额
df_pivot = df_long.pivot(index='城市', 
                         columns='月份', 
                         values='销售额')

实战案例:电商订单数据索引展开

原始数据问题分析

假设我们有一份按季度统计的订单金额,原始数据如下:

# 模拟数据
orders = pd.DataFrame({
    '年份': [2023, 2023, 2024, 2024],
    '季度': ['Q1', 'Q2', 'Q1', 'Q2'],
    '金额': [5000, 6000, 7000, 8000],
    '城市': ['上海', '上海', '北京', '北京']
})

问题:每个城市只有一行数据,但季度信息被拆成多行,我们需要将季度展开为独立列,方便横向对比。

分步代码实现

Step 1: 设置多级索引并展开

# 设置城市+年份为行索引,季度为列索引
df_index = orders.set_index(['城市', '年份', '季度']).unstack(level='季度')

Step 2: 使用pivot_table聚合

df_wide = orders.pivot_table(
    index=['城市', '年份'],
    columns='季度',
    values='金额',
    aggfunc='sum'  # 如果存在重复聚合
).reset_index()

结果:行索引 城市+年份 保持不变,季度 Q1/Q2 成为独立列。

Step 3: 处理多级列名

展开后列名可能是多级索引,使用 .columns.map('_'.join) 扁平化:

df_wide.columns = ['_'.join(col).strip('_') for col in df_wide.columns]

常见问题与SEO优化问答

Q1: 索引展开后数据行数变化异常?

原因

  • unstack() 会在索引组合不完整时自动插入NaN
  • pivot() 遇到重复索引值会报错(需使用 pivot_table

解决方法
✅ 先检查索引是否唯一:df.index.is_unique
✅ 使用 fill_value=0 填充缺失值
✅ 对重复数据用 pivot_table(aggfunc='mean') 聚合

Q2: 多层索引如何只展开某一层?

场景:有3级索引(城市、年份、季度),只展开按季度列。

df.unstack(level='季度')  # 按名称指定层级
# 或
df.unstack(level=2)       # 按层级位置(从0开始)

如果只想保留某几个层级作为新列,可使用 reset_index(level=[0,1]) 将指定层级转为普通列,再对剩余层级展开。


索引展开的最佳实践

  1. 先分析数据结构:明确哪些信息在行索引中,哪些在列索引中
  2. 选择合适方法
    • 行转列 → unstack / pivot
    • 列转行 → stack / melt
  3. 处理索引重复:在展开前用 groupby+agg 聚合重复值
  4. 命名规范:展开后及时扁平化列名,便于后续SQL或机器学习使用

实际项目中,索引展开往往需要结合数据透视表和聚合函数,建议将以上方法组合使用,例如先 groupby 聚合,再 unstack 展开,最后用 reset_index 恢复扁平表结构。


延伸思考
如果你遇到的是时间序列数据,推荐使用 pandas.date_range 配合 asfreq 先填充缺失时间点,再展开索引,对于超大数据集,注意 melt 可能产生内存膨胀,此时可先用 pivot_table 压缩后再转换。

本文案例代码已测试通过,可直接复制运行,如需完整数据集或进阶案例,欢迎搜索“Pandas数据重塑实战”。

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