如何用Group by、Pivot_table、Stack&Unstack重塑Pandas DataFrame(非聚合)
Hey there! 我太懂这种感觉了——对着一堆讲聚合的笔记,想做个纯结构重塑却卡得要死,pivot_table试了半天连第一步都走不通,简直头大😅
既然你不需要任何聚合操作,那**set_index + unstack绝对是最顺手的工具,另外如果你的数据没有重复的分组组合,pivot**也能直接搞定。下面我用一个贴近常见场景的示例来演示具体代码:
先明确示例场景
假设你的原始DataFrame长这样(如果结构不同,只要调整列名就行):
import pandas as pd # 原始DataFrame df = pd.DataFrame({ "Category": ["A", "A", "A", "B", "B"], "SubCategory": ["A1", "A1", "A2", "B1", "B1"], "Item": ["X", "Y", "X", "X", "Y"], "Value": [10, 20, 15, 5, 25] })
目标是转成二级列索引的格式(行是Item,列是Category→SubCategory,值是Value):
| Item | A | B | ||
|---|---|---|---|---|
| A1 | A2 | B1 | ||
| X Y | X | X Y | ||
| 10 20 | 15 | 5 25 |
方法1:Set Index + Unstack(推荐,纯重塑无聚合)
这是最灵活的方式,完全不需要聚合,核心是把要转成层级的列设置为行索引,再把索引层级转成列:
# 1. 将需要作为层级的列设置为多重行索引 # 顺序:行索引(Item)→ 要转成列层级的字段(Category, SubCategory) stacked = df.set_index(["Item", "Category", "SubCategory"])["Value"] # 2. 把后面两层索引(Category, SubCategory)转成列的二级层级 result = stacked.unstack(level=[1, 2]) # 3. 可选:整理列名的显示(如果需要更清晰的层级) result.columns = result.columns.reorder_levels(["Category", "SubCategory"]) result = result.sort_index(axis=1)
执行后就得到了你要的二级列索引结构,全程没有任何聚合操作——因为unstack只是把行索引的层级平移到列上,只要原始数据的索引组合是唯一的就不会报错。
方法2:Pivot(适合无重复组合的场景)
如果你的数据中(Category, SubCategory, Item)的组合是唯一的(没有重复行),直接用pivot就能一步到位:
# 直接指定行索引、列的层级、值字段 result = df.pivot( index="Item", columns=["Category", "SubCategory"], values="Value" )
这个方法更简洁,但要注意:如果存在重复的组合,pivot会报错,这时候才需要用pivot_table加聚合函数(但你不需要,所以先确认数据唯一性)。
前置检查:确保无重复组合
为了避免报错,建议先检查是否有重复的分组组合:
# 检查是否有重复的(Category, SubCategory, Item)组合 duplicates = df.duplicated(subset=["Category", "SubCategory", "Item"], keep=False) if duplicates.any(): print("⚠️ 注意:存在重复的分组组合,请先去重或处理后再重塑!")
如果你的目标格式和示例略有不同(比如行是二级索引,列是Item),只要调整set_index的顺序和unstack的层级就行——核心逻辑都是把层级字段转成索引,再平移到行/列,完全不需要依赖聚合操作~
内容的提问来源于stack exchange,提问作者kiltannen
相关产品推荐
相关产品推荐

