这是对pivot 和unstack 之间差异的规范答案的尝试。关于重塑的完整指南,reshaping and pivot tables 上的 pandas 官方文档是必读的。
pivot 和 unstack 执行大致相同的操作,但它们在不同的逻辑级别上操作:分别为 列 和 索引级别。
我将使用这个示例数据框作为输入:
df = pd.DataFrame({'col1': list('ABCABC'),
'col2': list('aaabbb'),
'col3': list('uvwxyz'),
})
col1 col2 col3
0 A a u
1 B a v
2 C a w
3 A b x
4 B b y
5 C b z
pandas.DataFrame.pivot 对列进行操作
注意。当index 参数未使用时,它将使用当前索引。
df.pivot(index='col1', columns='col2', values='col3')
col2 a b
col1
A u x
B v y
C w z
在 MultiIndexes 上使用 unstack
这里有两个用例,无论输入是 Series 还是 DataFrame。
我们将首先从初始 DataFrame 生成一个带有 MultIndex 的系列:
series = df.set_index(['col1', 'col2'])['col3']
col1 col2
A a u
B a v
C a w
A b x
B b y
C b z
Name: col3, dtype: object
我们看到数据与原始DataFrame非常相似,但col1和col2现在是索引级别,数据本身现在是一维的(即一个Series)
现在,我们可以应用unstack 默认将最右边(最后一个)索引级别作为列来旋转以生成 DataFrame。有很多方法可以指定要取消堆叠的索引级别,因此所有这些选项都是等效的:
series.unstack()
series.unstack('col2') # by level name
series.unstack(1) # by level position from the left
series.unstack(-1) # by level position from the end (-1 = last)
col2 a b
col1
A u x
B v y
C w z
这意味着df.pivot(index='col1', columns='col2', values='col3') 和df.set_index(['col1', 'col2'])['col3'].unstack() 在逻辑上是等价的。
unstack 的 DataFrame 版本与 Series 的版本非常相似,不同之处在于,由于数据已经是二维的,它将为列创建额外的索引级别。
df.set_index(['col1', 'col2']).unstack(level='col2')
col3
col2 a b
col1
A u x
B v y
C w z
同样,使用pivot,通过将列表封装的列名传递给values,可以获得相同的输出:
df.pivot(index='col1', columns='col2', values=['col3'])
col3
col2 a b
col1
A u x
B v y
C w z