熊猫:按列a作为索引转置列(b,c,d)

时间:2019-10-07 17:01:32

标签: python pandas pivot

我有一个数据框:

import pandas as pd 
import numpy as np 
data = pd.DataFrame({'file':['file1','file1','file1','file2','file2','file2' ], 'x': [1,2,3,1,2,4], 'y': [10,20,30,10, 20, 40], 'norm_y': [2,4,6,2,4,8]})

print (data)

out: 
    file  x   y  norm_y
0  file1  1  10       2
1  file1  2  20       4
2  file1  3  30       6
3  file2  1  10       2
4  file2  2  20       4
5  file2  4  40       8

我要打印它,以便:

  • 文件是主要索引
  • x,y,z是子索引

看起来像这样:

    file          
0         x     1  2  3
1  file1  y     10 20 30
2         ynorm 2  4  6
3         x     1  2  4
4  file2  y     10 20 40
5         ynorm 2  4  8

我认为答案将是这样的:

  • 设置行索引:data.set_index(['file'])
  • 转置x,y,ynorm列

5 个答案:

答案 0 :(得分:3)

这是一个pivot问题的核心,但实际上并不是一个简单的问题。


df.assign(
  key=df.groupby('file').cumcount()).set_index(['file', 'key']).stack().unstack('key')

key            0   1   2
file
file1 x        1   2   3
      y       10  20  30
      norm_y   2   4   6
file2 x        1   2   4
      y       10  20  40
      norm_y   2   4   8

答案 1 :(得分:3)

您只需要一点想象力即可:

data.set_index('file').groupby(level=0).apply(lambda x: x.T)

输出:

file          file2  file2  file2
file                             
file1 x           1      2      3
      y          10     20     30
      norm_y      2      4      6
file2 x           1      2      4
      y          10     20     40
      norm_y      2      4      8

答案 2 :(得分:2)

您可以这样做:

df['col' ] = df.groupby('file').cumcount()+1
df.pivot_table(index='file', columns='col').stack(level=0)

输出:

col            1   2   3
file                    
file1 norm_y   2   4   6
      x        1   2   3
      y       10  20  30
file2 norm_y   2   4   8
      x        1   2   4
      y       10  20  40

答案 3 :(得分:1)

numpy重塑

fil, var, val = df.melt('file').values.T

new = pd.DataFrame(np.hstack([fil.reshape(-1,3)[:, 0].reshape(-1,1), 
                              var.reshape(-1,3)[:, 0].reshape(-1,1), 
                              val.reshape(-1,3)]))\
        .set_index([0,1])\
        .sort_index()

               2   3   4
0     1                 
file1 norm_y   2   4   6
      x        1   2   3
      y       10  20  30
file2 norm_y   2   4   8
      x        1   2   4
      y       10  20  40

答案 4 :(得分:0)

尝试一下。

(
    pd.melt(data, id_vars='file', value_vars=['x', 'y', 'norm_y']) #Unstacks the data
    .groupby(['file', 'variable'])['value'] #restacks with file and variable as index
    .aggregate(lambda x: tuple(x)) #splits out values in to a column
    .apply(pd.Series) #turns them into separate columns
)