多级Pandas数据框中自定义排序列

7

背景

我有一个具有两级列但只有一级行的大型数据框,并尝试按以下方式对其进行排序: 级别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,但仍只得到按字母顺序排列的结果。

2个回答

15
你可以使用reindex_axis来实现此目的,它可以接受labels arg、axis和level参数:
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

1
@jezrael,我的理解是,OP想要更改列的顺序,而不仅仅是重新标记它们。 - EdChum
1
抱歉,我做得不好。 - jezrael
1
df.reindex(columns=list("FML"), level=1) 应该就足够了。不过无论如何,回答得很好。 - Nickil Maveli
1
@jezrael 不用担心,最初我以为这只是一个简单的.columns.set_levels问题,但我再次查看了一下。 - EdChum
1
@EdChum:没关系。现在你已经完全弄清楚了 :-) - Nickil Maveli
显示剩余5条评论

3

在创建数据框时设置索引

如果您不想在之后更改数据框,则可以在定义顺序的索引中将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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接