Pandas转换多索引标头



我有一个数据帧,格式如下:

price                cost              
id   mean   max    min    mean   max    min  
0     1     1      1       1     2      3
1     2     2      2       1     2      3
2     3     3      3       1     2      3

我想将其更改为以下内容:

id      mean   max    min    type
0       1     1      1     price    
1       2     2      2     price  
2       3     3      3     price
0       1     1      1     cost       
1       2     2      2     cost   
2       3     3      3     cost 

尝试stack()方法、drop()方法、reset_index()方法和rename()方法:

df=(df.stack(0)
.drop('id',1)
.reset_index()
.rename(columns={'level_0':'id','level_1':'type'}))

df:输出

id  type    max     mean    min
0   0   cost    2       1       1
1   0   price   1       1       3
2   1   cost    2       1       2
3   1   price   2       2       3
4   2   cost    2       1       3
5   2   price   3       3       3

让我们尝试rename_axis+stack,然后使用sort_values

out = df.rename_axis(['type',None],axis=1).stack(0).reset_index().sort_values('type')
Out[294]: 
id   type  max  mean  min
0   0   cost    2     1    3
2   1   cost    2     1    3
4   2   cost    2     1    3
1   0  price    1     1    1
3   1  price    2     2    2
5   2  price    3     3    3

这就是表的长格式和短格式之间的区别。

您可以使用.stack().reset_index().rename()来转换所需的格式。

df.stack(0).reset_index(1).rename(columns={'level_1': 'type'})

这里有一篇很棒的文章,用很好的可视化描述了堆叠和卸载是如何工作的。

下面是一步一步的结果:

>>> df
price         cost        
mean max min mean max min
0     1   1   1    1   2   3
1     2   2   2    1   2   3
2     3   3   3    1   2   3
>>> df.stack(level=0)
max  mean  min
0 cost     2     1    3
price    1     1    1
1 cost     2     1    3
price    2     2    2
2 cost     2     1    3
price    3     3    3
>>> df.stack(level=0).reset_index(level=1)
level_1  max  mean  min
0    cost    2     1    3
0   price    1     1    1
1    cost    2     1    3
1   price    2     2    2
2    cost    2     1    3
2   price    3     3    3
>>> df.stack(level=0).reset_index(level=1).rename(columns={'level_1': 'type'})
type max  mean  min
0   cost    2     1    3
0  price    1     1    1
1   cost    2     1    3
1  price    2     2    2
2   cost    2     1    3
2  price    3     3    3

如果您需要维护id列(它不是一个无用的自动递增列(,您可以添加一个额外的set_indexreset_index来保留该列:

>>> df.set_index('id').stack(0).reset_index(1) 
.rename(columns={'level_1': 'type'}).reset_index()
id   type  max  mean  min
0   0   cost    2     1    3
1   0  price    1     1    1
2   1   cost    2     1    3
3   1  price    2     2    2
4   2   cost    2     1    3
5   2  price    3     3    3

最新更新