Pandas转换CSV表格:unstack()/pivot()/crosstab()该选哪个?
Pandas表格重塑:从宽格式转目标结构的解决方案
问题背景
原始CSV数据格式:
| Unnamed:5 | Week5 | Week4 | Week3 |
|---|---|---|---|
| Quartiles | 2 | 3 | 4 |
| CR | 1 | 2 | 5 |
| KPI | 4 | 5 | 2 |
| Quartiles | 2 | 3 | 4 |
| CR | 1 | 2 | 3 |
| KPI | 3 | 4 | 1 |
需要转换为如下结构:
| Week | Quartiles | CR | KPI |
|---|---|---|---|
| Week5 | 2 | 1 | 4 |
| Week4 | 3 | 2 | 5 |
| Week3 | 4 | 5 | 2 |
| Week5 | 2 | 1 | 3 |
| Week4 | 3 | 2 | 4 |
| Week3 | 4 | 3 | 1 |
作为Pandas新手,尝试过unstack()、reset_index()和pivot_table()未达预期,需要明确正确的方法。
正确解决方案:melt() + pivot()组合
这里核心是先把宽格式转长格式,再重塑为目标宽格式,同时需要给每3行的指标组添加标识,避免重塑时数据混淆。
代码步骤
- 导入Pandas并构造原始数据(如果是从CSV读取,用
pd.read_csv()即可)
import pandas as pd # 模拟原始CSV数据 data = { 'Unnamed:5': ['Quartiles', 'CR', 'KPI', 'Quartiles', 'CR', 'KPI'], 'Week5': [2, 1, 4, 2, 1, 3], 'Week4': [3, 2, 5, 3, 2, 4], 'Week3': [4, 5, 2, 4, 3, 1] } df = pd.DataFrame(data)
- 重命名指标列并添加组ID
# 把Unnamed:5重命名为Metric,明确这是指标列 df = df.rename(columns={'Unnamed:5': 'Metric'}) # 每3行为一组,添加Group标识(避免不同组的Week数据被错误合并) df['Group'] = df.index // 3
- 转长格式+重塑为目标结构
# 使用melt把Week列转为行,得到(Group, Metric, Week, Value)的长格式 melted_df = df.melt(id_vars=['Group', 'Metric'], var_name='Week', value_name='Value') # 使用pivot把Metric转为列,得到目标宽格式 result_df = melted_df.pivot( index=['Group', 'Week'], columns='Metric', values='Value' ).reset_index() # 清理不需要的Group列,调整列顺序匹配目标结构 result_df = result_df.drop('Group', axis=1)[['Week', 'Quartiles', 'CR', 'KPI']]
执行后result_df就是你需要的目标表格。
方法选择说明
pivot_table():默认会对重复索引进行聚合(比如求和、均值),这里不需要聚合操作,用它会多此一举,甚至可能导致数据错误。unstack():需要先构建合适的多层索引,配合分组也能实现,但步骤比melt()+pivot更繁琐,新手不易理解。crosstab():用于统计类别变量的交叉频数/频率,完全不适合这种单纯的表格重塑场景。melt()+pivot():逻辑清晰,先拆宽为长,再转长为宽,完美匹配当前的结构转换需求,是最适合的方案。
内容的提问来源于stack exchange,提问作者Krishnamoorthy
相关产品推荐
相关产品推荐

