【问题标题】:Pandas, convert MultiIndex data frame some columns into rowsPandas,将 MultiIndex 数据框的某些列转换为行
【发布时间】:2020-03-30 10:30:56
【问题描述】:

我有一个这样的 MultiIndex 数据框:

col_type1  col_type2   col_a           col_b           colc
col_type1  col_type2   col_x  col_y    col_x col_y    col_x  col_y
type11     type21      10     100      11    101      12     102
type12     type22      20     200      21    201      22     202
type13     type23      30     300      31    301      32     302

这是创建数据框代码:

pd.DataFrame.from_dict(
{('col_type1', 'col_type1'): {0: 'type11', 1: 'type12', 2: 'type13'},
 ('col_type2', 'col_type2'): {0: 'type21', 1: 'type22', 2: 'type23'},
 ('col_a', 'col_x'): {0: '10', 1: '20', 2: '30'},
 ('col_a', 'col_y'): {0: '100', 1: '200', 2: '300'},
 ('col_b', 'col_x'): {0: '11', 1: '21', 2: '31'},
 ('col_b', 'col_y'): {0: '101', 1: '201', 2: '301'},
 ('col_c', 'col_x'): {0: '12', 1: '22', 2: '32'},
 ('col_c', 'col_y'): {0: '102', 1: '202', 2: '302'}})

我想把这个数据框融合成这种格式,保留col_type1col_type2,并将第一级列转换为行:

col_type1 col_type2  col_convert col_x  col_y
type11    type21     col_a       10     100  
type11    type21     col_b       11     101
type11    type21     col_c       12     102
type12    type22     col_a       20     200  
type12    type22     col_b       21     201
type12    type22     col_c       22     202
type13    type23     col_a       30     300  
type13    type23     col_b       31     301
type13    type23     col_c       32     302

我试过melt(),这个方法可以设置col_level

但是当我将它设置为0时,它会失去级别1

当我将其设置为1 时,它将失去级别0

我试过unstack(),这个方法不能设置col_level,

我必须先过滤 type1 并删除列 col_type

然后unstack数据两次,然后将col_type追加为type1

还有type2type3...

有更好的方法吗?

【问题讨论】:

    标签: pandas multi-index


    【解决方案1】:

    更新:

    df = pd.DataFrame.from_dict(
    {('col_type1', 'col_type1'): {0: 'type11', 1: 'type12', 2: 'type13'},
     ('col_type2', 'col_type2'): {0: 'type21', 1: 'type22', 2: 'type23'},
     ('col_a', 'col_x'): {0: '10', 1: '20', 2: '30'},
     ('col_a', 'col_y'): {0: '100', 1: '200', 2: '300'},
     ('col_b', 'col_x'): {0: '11', 1: '21', 2: '31'},
     ('col_b', 'col_y'): {0: '101', 1: '201', 2: '301'},
     ('col_c', 'col_x'): {0: '12', 1: '22', 2: '32'},
     ('col_c', 'col_y'): {0: '102', 1: '202', 2: '302'}})
    
    df.set_index([('col_type1', 'col_type1'),('col_type2', 'col_type2')])\
      .stack(0)\
      .reset_index()\
      .rename(columns={('col_type1', 'col_type1'):'col_type1',
                       ('col_type2', 'col_type2'):'col_type2',
                       'level_2':'col_convert'})
    

    输出:

      col_type1 col_type2 col_convert col_x col_y
    0    type11    type21       col_a    10   100
    1    type11    type21       col_b    11   101
    2    type11    type21       col_c    12   102
    3    type12    type22       col_a    20   200
    4    type12    type22       col_b    21   201
    5    type12    type22       col_c    22   202
    6    type13    type23       col_a    30   300
    7    type13    type23       col_b    31   301
    8    type13    type23       col_c    32   302
    

    尝试,堆叠多索引列的零级:

    df.stack(0).reset_index()
    

    输出:

           0 level_1  col_x  col_y
    0  type1   col_a     10    100
    1  type1   col_b     11    101
    2  type1   col_c     12    102
    3  type2   col_a     20    200
    4  type2   col_b     21    201
    5  type2   col_c     22    202
    6  type3   col_a     30    300
    7  type3   col_b     31    301
    8  type3   col_c     32    302
    

    【讨论】:

    • 感谢您的回答。我试过了,但在我的 level_0 中不是type1, type2, type3,它是0 0 0, 1 1 1, 2 2 2,我有些行col_type type1 NaN NaN, col_type type2 NaN NaN, col_type type3 NaN NaN
    • 问题中显示的数据框的前两行是否在索引中?您可以执行 df.to_dict() 并将该输出发布到您的问题中吗?或者更好地将生成数据框的代码放在问题中?
    • 谢谢,我已经把创建数据框的代码放在我的问题里了,你能再看看吗
    • @fisheep 使用您的数据框和我更新的代码,它似乎可以工作。
    猜你喜欢
    • 1970-01-01
    • 2023-03-02
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    • 2020-11-05
    • 2021-05-28
    相关资源
    最近更新 更多