在分类汇总数据中,stack()
和 unstack()
是进行层次化索引的重要操作。
层次化索引就是对索引进行层次化分类,包含行索引、列索引。
常见的数据层次化结构包含两种:表格(横表)、“花括号”(纵表)。
表格在行列方向上均有索引,花括号结构只有“列方向”上的索引。
其实,应用 stack()
和 unstack()
只需要记住:
-
stack
—— 将数据从”表格结构“变成”花括号结构“,即将其列索引变成行索引。 -
unstack
—— 数据从”花括号结构“变成”表格结构“,即要将其中一层的行索引变成列索引。如果是多层索引,则以上函数是针对内层索引,利用level
参数可以选择具体哪层索引。
【小技巧】使用 stack()
的时候,level
等于哪一个,哪一个就消失,出现在行里。
【小技巧】使用 unstack()
的时候,level
等于哪一个,哪一个就消失,出现在列里。
一、stack堆叠
stack()
返回一个 Series
, 需要通过 reset_index()
进行重置索引。
使用语法:
DataFrame.stack(level=-1, dropna=True)
- 单索引
# 构建测试集
import pandas as pd
import numpy as np
df_size = 10
df = pd.DataFrame({
'a': np.random.rand(df_size),
'b': np.random.rand(df_size),
'c': np.random.rand(df_size),
'd': np.random.rand(df_size),
'e': np.random.rand(df_size)
})
print(df)
# 不指定参数 所有列都将被堆叠
data = df.stack() # 一维Series
'''
0 a 0.374002
b 0.289687
c 0.720090
d 0.645252
e 0.063648
1 a 0.012059
b 0.228809
c 0.018861
d 0.511085
e 0.002751
dtype: float64
'''
# 重设索引
df.stack().reset_index()
'''
level_0 level_1 0
0 0 a 0.374002
1 0 b 0.289687
2 0 c 0.720090
3 0 d 0.645252
4 0 e 0.063648
'''
使用 stack
函数,将数据框的列索引转变成行索引(第二层),得到一个层次化的 Series
。
- 多层索引
multicol1 = pd.MultiIndex.from_tuples([('weight', 'kg'),
('weight', 'pounds')])
df_multi = pd.DataFrame([[1, 2], [2, 4]],
index=['cat', 'dog'],
columns=multicol1)
df_multi.stack() # 内层列索引
df_multi.stack(level=1) # 同上 内层列索引
df_multi.stack(level=0) # 第一层列索引
# 删除空数据行
df_multi.stack(dropna=True)
二、unstack反堆叠
使用语法:
DataFrame.unstack(level=-1, fill_value=None)
- 单索引
# 反堆叠
df.stack().unstack()
# 通过level参数选择堆叠的索引
df.stack().unstack(level=0)
'''
0 1 2 ... 7 8 9
a 0.521016 0.349603 0.140595 ... 0.578615 0.629479 0.896016
b 0.043503 0.540825 0.379667 ... 0.570826 0.484303 0.922657
c 0.674632 0.044395 0.931385 ... 0.974338 0.228876 0.081472
d 0.960165 0.859809 0.713214 ... 0.247970 0.665914 0.653477
e 0.330087 0.453380 0.293309 ... 0.885709 0.591437 0.842542
'''
# 列标签填充
df.stack().unstack(level=0, fill_value='type')
利用 unstack
函数,将生成后的第二层行索引转变成列索引(默认内层索引,level=-1),恢复原始数据框。
- 多层索引
df_multi2 = df_multi.stack(level=0)
df_multi2.unstack(level=0)
'''
kg pounds
cat dog cat dog
weight 1 2 2 4
'''
三、reshape变形
实现 Series
数据变形。
import pandas as pd
import numpy as np
data = pd.DataFrame(np.arange(12).reshape(3,4),
index=pd.Index(['street1','street2','street3']),
columns=pd.Index(['store1','store2','store3','store4']))
print(data)
参考链接:Python: Pandas中stack和unstack的形象理解
参考链接:pandas中stack的用法