按 multiIndex python pandas 数据帧在另一个数据帧上出现的顺序排序

Sort multiIndex python pandas dataframe by the order they appear on another data frame

我有一个这样的数据框df

                 a   b
 id   no   name   
T01  101   foo   1  
T32  102   bar   2  
T10  103   baz   4  

其中索引为 id, no and name。我有另一个数据框 df2 具有我希望的索引顺序

    no
0  103
1  101
2  102

我需要数据框

                 a   b
 id   no   name  
T10  103   baz   4   
T01  101   foo   1  
T32  102   bar   2  

我见过使用 df.loc[df2.no.values]df.reindex(df2.no) 但是因为我有多索引数据帧它似乎不起作用

我应该用什么来将键 no 中的 df 排序为 df2 中的顺序?

一种可能的解决方案 reset_index, reindex and last set_index

print df1.reset_index(level=['id','name'])
         .reindex(df2.no)
         .reset_index()
         .set_index(['id','no','name'])

              a    b
id  no  name        
T10 103 baz   4  
T01 101 foo   1  
T32 102 bar   2  

如果级别顺序不重要:

print df1.reset_index(level=['id','name'])
         .reindex(df2.no)
         .set_index(['id','name'], append=True)

              a    b
no  id  name        
103 T10 baz   4  
101 T01 foo   1  
102 T32 bar   2  

时间:

In [77]: %timeit df1.unstack([0, 2]).ix[df2.no].stack([1, 2]).swaplevel(0, 1)
10 loops, best of 3: 18.8 ms per loop

In [78]: %timeit df1.reset_index(level=['id','name']).reindex(df2.no).reset_index().set_index(['id','no','name'])
The slowest run took 4.41 times longer than the fastest. This could mean that an intermediate result is being cached 
100 loops, best of 3: 4.41 ms per loop

解决方案

df.unstack([0, 2]).ix[df2.no].stack([1, 2]).swaplevel(0, 1)

说明

unstack([0, 2]) 将第 1 级和第 3 级索引放入 [-2, -1] 级列。这隔离了您关心的级别。

ix[df2.no]按照您喜欢的顺序订购剩余的级别。

stack([1, 2]) 从列中获取级别并将它们放回索引中。

swaplevel(0, 1) 将索引级别恢复为原始顺序。