unstack() 是 pandas 中用于 重塑(reshape) 数据的一个重要函数,主要用于将 MultiIndex(层次化索引)的 Series 或 DataFrame 中的 内层索引(或指定层级)“旋转”为列,从而将“长格式”数据转换为“宽格式”。
📌 基本功能
对一个具有 多层索引(MultiIndex) 的对象(通常是 Series 或 DataFrame),unstack() 会:
默认将最内层(最后一层)的索引 转换为新的 列(columns)
原来的外层索引保留为 行索引(index)
如果某些组合不存在,结果中会填充
NaN(可用fill_value参数替换)
✅ 示例说明
假设你有如下数据:
import pandas as pd
data = pd.DataFrame({
'store': ['A', 'A', 'B', 'B', 'A'],
'product': ['X', 'Y', 'X', 'Z', 'X'],
'sales': [10, 20, 30, 40, 50]
})执行分组计数:
s = data.groupby('store')['product'].value_counts()
print(s)输出是一个 MultiIndex Series:
store product
A X 2
Y 1
B X 1
Z 1
Name: product, dtype: int64现在使用 unstack():
df_wide = s.unstack(fill_value=0)
print(df_wide)结果:
product X Y Z
store
A 2 1 0
B 1 0 1行索引:
store(外层索引)列索引:
product(原内层索引)值:计数
用
fill_value=0将缺失值(如 B-Y、A-Z)设为 0
🔧 常用参数
你也可以指定层级名称或编号:
s.unstack(level='product') # 如果索引有名字
s.unstack(level=1) # 如果 product 是第1层(0-based)💡 与 pivot / pivot_table 的区别
unstack()作用于 已有 MultiIndex 的对象pivot()作用于 普通 DataFrame,需要指定index,columns,valuesunstack()更适合在groupby+value_counts()/size()等操作后使用
unstack() 和 pivot_table() 都是 pandas 中用于 重塑数据(reshape) 的函数,都能将“长格式”数据转换为“宽格式”,但它们在 使用前提、灵活性、功能定位 上有本质区别。
🔍 核心区别总结
🧪 举例对比
场景:统计每个门店每种产品的销售次数
原始数据:
import pandas as pd
df = pd.DataFrame({
'store': ['A', 'A', 'B', 'A', 'B'],
'product': ['X', 'Y', 'X', 'X', 'Z'],
'sales': [10, 20, 30, 40, 50]
})✅ 使用 unstack()(需先聚合)
# 先 groupby 得到 MultiIndex Series
s = df.groupby(['store', 'product']).size() # 或 value_counts()
print(s)
# store product
# A X 2
# Y 1
# B X 1
# Z 1
# 再 unstack
result1 = s.unstack(fill_value=0)⚠️ 注意:unstack() 不能直接作用于原始 df,必须已有 MultiIndex。
✅ 使用 pivot_table()(直接从原始数据透视)
result2 = pd.pivot_table(
df,
index='store',
columns='product',
values='sales', # 可选:若不指定 values,会用所有数值列
aggfunc='count', # 聚合函数:统计次数
fill_value=0
)或者统计销售额总和:
result_sum = pd.pivot_table(df, index='store', columns='product', values='sales', aggfunc='sum', fill_value=0)✅ pivot_table() 可直接处理原始数据,并自动聚合重复项。
❗ 关键差异点详解
1. 对重复键的处理
unstack():要求(index_level_0, index_level_1)唯一,否则会报错(如ValueError: Index contains duplicate entries)。pivot_table():专门设计用于处理重复键,通过aggfunc自动聚合。
2. 是否需要预聚合
unstack():必须先通过groupby、value_counts等得到聚合后的 MultiIndex 数据。pivot_table():一步到位,聚合 + 透视同时完成。
3. 功能范围
unstack()是 纯结构变换工具(reshape only)。pivot_table()是 数据分析工具(reshape + aggregate + summarize)。
✅ 如何选择?
💡 补充:pivot() vs pivot_table()
pivot():类似unstack(),但作用于普通 DataFrame,不支持聚合,遇到重复键会报错。pivot_table():是pivot()的增强版,支持聚合,更健壮。
总结一句话:
unstack() 是“结构转换器”,pivot_table() 是“数据透视分析器”。前者用于已聚合的 MultiIndex 数据重塑,后者用于从原始数据直接透视汇总。