代码之家  ›  专栏  ›  技术社区  ›  mike01010

熊猫:排序多级列

  •  1
  • mike01010  · 技术社区  · 1 月前

    我有以下熊猫数据帧:

    import pandas as pd
    data1 = [['01/01/2000', 101, 201, 301],
            ['01/02/2000', 102, 202, 302],
            ['01/03/2000', 103, 203, 303],]
    df1 = pd.DataFrame(data1, columns=['date', 'field1', 'field2', 'field3'])
    df1 = df1.set_index('date')
    data2 = [['01/01/2000', 101, 201, 301],
            ['01/02/2000', 102, 202, 302],
            ['01/03/2000', 103, 203, 303],]
    df2 = pd.DataFrame(data2, columns=['date', 'field2', 'field1', 'field3'])
    df2= df2.set_index('date')
    
    df = pd.concat([df1, df2], keys={'group1':df1, 'group2': df2 }, axis=1)
    df
    

    这会产生:

                group1                  group2
                field1  field2  field3  field2  field1  field3
    date                        
    01/01/2000  101     201     301     101     201     301
    01/02/2000  102     202     302     102     202     302
    01/03/2000  103     203     303     103     203     303
    

    我想按自定义顺序对组和字段进行排序。对于列的第1级,我尝试了以下操作:

    group_sort=['group2', 'group1']
    m = {k:v for k, v in enumerate(group_sort)}
    df = df.sort_index(axis=1, key=lambda x: x.map(m), level=1)
    df
    

    这会产生以下内容,这些内容与原始数据帧仍然相同:

                group1                  group2
                field2  field1  field3  field1  field2  field3
    date                        
    01/01/2000  101     201     301     101     201     301
    01/02/2000  102     202     302     102     202     302
    01/03/2000  103     203     303     103     203     303
    

    对于级别0(字段),我尝试过:

    field_sort=['field3', 'field2', 'field1']
    m = {k:v for k, v in enumerate(field_sort)}
    df = df.sort_index(axis=1, key=lambda x: x.map(m), level=0)
    df
    

    但这会产生:

                group1  group2  group1  group2  group1  group2
                field1  field1  field2  field2  field3  field3
    date                        
    01/01/2000  201     101     101     201     301     301
    01/02/2000  202     102     102     202     302     302
    01/03/2000  203     103     103     203     303     303
    

    所以我的问题是——如何对组和字段进行排序? 有没有更干净、更简洁或更有效的方法来做到这一点?

    我所期望的输出排序如下:

                group2                  group1
                field3  field2  field1  field3  field2  field1
    date                        
    01/01/2000  301     201     101     301     201     101
    01/02/2000  302     202     102     302     202     102
    01/03/2000  303     203     103     303     203     103
    

    谢谢

    1 回复  |  直到 1 月前
        1
  •  1
  •   sammywemmy    1 月前

    一个选项是使用reindex和sort_index的组合:

    (df
    .reindex(labels=field_sort,axis=1,level=1)
    .sort_index(level=0,axis=1, sort_remaining=False,ascending=False)
    )
    Out[23]:
               group2               group1
               field3 field2 field1 field3 field2 field1
    date
    01/01/2000    301    101    201    301    201    101
    01/02/2000    302    102    202    302    202    102
    01/03/2000    303    103    203    303    203    103
    

    一个更稳健的选择是创建一个MultiIndex并用它重新索引:

    headers = ['group2','group1']
    field_sort=['field3', 'field2', 'field1']
    df.reindex(columns=pd.MultiIndex.from_product([headers,field_sort]))
    Out[21]:
               group2               group1
               field3 field2 field1 field3 field2 field1
    date
    01/01/2000    301    101    201    301    201    101
    01/02/2000    302    102    202    302    202    102
    01/03/2000    303    103    203    303    203    103