为什么以及何时应该使用 stack() 和 unstack() 方法?

why and when should use a stack() and unstack() methods?

我对这两种方法感到很困惑,它们是: 栈()和拆栈() 我知道我应该在多索引的情况下使用它们,但是,我需要知道以下内容:

1-我不知道应该在什么地方使用stack或unstack
2- 为什么我应该使用它们

当我使用“pivot”时,我的理解是 pivot 将 Dataframe 转换为 unstack 形式,如果这是正确的,我需要知道为什么当我使用以下行代码时它会引发错误:

data.stack(level=1) # IndexError: Too many levels: Index has only 1 level, not 2

但是当我这样做时,它会运行:

data.unstack().stack(level=1)

有时,我看到堆栈有这样的 kwargs,level=-1 我不知道什么时候必须放置“-1”,那是什么意思

我知道我误解了很多东西,但我很困惑

所以,请问对理解这些术语有什么帮助吗?

提前谢谢

这是对pivot and unstack. For a complete guide on reshaping, pandas's official documentation on reshaping and pivot tables之间差异的规范回答的尝试,必读。

pivot and 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

在列上使用 pivot

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

在多索引上使用 unstack

无论输入是 Series 还是 DataFrame,这里都有两个用例。

pandas.Series.unstack

我们将首先从初始 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非常相似,但是col1col2现在是索引级别,数据本身现在是一维的(即一个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()在逻辑上是等价的。

pandas.DataFrame.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

同样,通过将列表封装的列名传递给 values:

,可以使用 pivot 获得相同的输出
df.pivot(index='col1', columns='col2', values=['col3'])
     col3   
col2    a  b
col1        
A       u  x
B       v  y
C       w  z