【问题标题】:Custom sorting columns in multi level pandas dataframe多级熊猫数据框中的自定义排序列
【发布时间】:2017-08-21 17:53:23
【问题描述】:

背景

我有一个大数据框,它有 2 个级别的列,但有 1 个级别的行,我正在尝试按如下方式对其进行排序: 0级:按字母顺序; 级别 1:自定义排序。

示例

import pandas as pd
dictionary = {'A' : {'M': [1,2,3,4,5],
                     'L': [6,7,8,9,1],
                     'F': [3,5,1,3,5]  },
              'C' : {'M': [2,3,4,5,6],
                     'L': [7,8,9,1,2],
                     'F': [0,1,6,3,5]  },
              'B' : {'M': [1,5,2,5,3],
                     'L': [9,5,6,3,4],
                     'F': [6,2,7,1,5] }
         }
reform = {(outerKey, innerKey): values for outerKey, innerDict in dictionary.iteritems() for innerKey, values in innerDict.iteritems()}
pd.DataFrame(reform,index=['g','h','i','j','k'])

我现在拥有的是

#        A          B           C
#        F  L   M   F   L   M   F   L   M
#    g  3   6   1   6   9   1   0   7   2
#    h  5   7   2   2   5   5   1   8   3
#    i  1   8   3   7   6   2   6   9   4
#    j  3   9   4   1   3   5   3   1   5
#    k  5   1   5   5   4   3   5   2   6

问题

如何将列的顺序指定为级别 0 的 A、B、C 和级别 1 的 F、M、L?

### OUT
#        A          B           C
#        F  M   L   F   M   L   F   M   L

我正在尝试使用 pd.IndexSlice.loc,但我仍然只能得到字母顺序。

【问题讨论】:

    标签: python sorting pandas


    【解决方案1】:

    您可以使用reindex_axis 实现此目的,它接受标签 arg、轴和级别:

    In [20]:
    df = df.reindex_axis(list('FML'), axis=1, level=1)
    df
    
    Out[20]:
       A        B        C      
       F  M  L  F  M  L  F  M  L
    g  3  1  6  6  1  9  0  2  7
    h  5  2  7  2  5  5  1  3  8
    i  1  3  8  7  2  6  6  4  9
    j  3  4  9  1  5  3  3  5  1
    k  5  5  1  5  3  4  5  6  2
    

    感谢@Nickli Maveli,您也可以使用reindex 来实现相同的目的:

    In [22]:
    df = df.reindex(columns=list('FML'), level=1)
    df
    
    Out[22]:
       A        B        C      
       F  M  L  F  M  L  F  M  L
    g  3  1  6  6  1  9  0  2  7
    h  5  2  7  2  5  5  1  3  8
    i  1  3  8  7  2  6  6  4  9
    j  3  4  9  1  5  3  3  5  1
    k  5  5  1  5  3  4  5  6  2
    

    【讨论】:

    • @jezrael 什么问题,OP想要改变列顺序,而不仅仅是重新标记它们是我的理解
    • 对不起,我做得不好。
    • df.reindex(columns=list("FML"), level=1) 应该足够了。但无论如何,很好的答案。
    • @jezrael 别担心,本来我以为这只是一个简单的.columns.set_levels 问题,但我又看了一遍
    • 是的,我看到的是原版。我认为这很糟糕
    【解决方案2】:

    在创建数据框时设置索引

    如果您不想在之后更改数据框,您可以为 pd.DataFrame 构造函数提供一个您已经定义顺序的索引。

    显式解决方案

    columns = pd.Index([('A', 'F'), ('A', 'M'), ('A', 'L'), ('B', 'F'), ('B', 'M'), ('B', 'L'),('C', 'F'), ('C', 'M'), ('C', 'L')])
    pd.DataFrame(reform,index=['g','h','i','j','k'], columns=columns)
    

    复合解决方案

    columns = pd.Index([(level_0, level_1) for level_0 in "ABC" for level_1 in "FML"])
    pd.DataFrame(reform,index=['g','h','i','j','k'], columns=columns)
    

    两者都给出

       A        B        C      
       F  M  L  F  M  L  F  M  L
    g  3  1  6  6  1  9  0  2  7
    h  5  2  7  2  5  5  1  3  8
    i  1  3  8  7  2  6  6  4  9
    j  3  4  9  1  5  3  3  5  1
    k  5  5  1  5  3  4  5  6  2
    

    【讨论】:

      猜你喜欢
      • 2013-10-12
      • 2021-10-14
      • 2021-12-20
      • 2012-11-30
      • 1970-01-01
      • 1970-01-01
      • 2021-09-27
      • 1970-01-01
      相关资源
      最近更新 更多