使用“.loc”访问多索引数据帧时如何保留列顺序?

nor*_*ius 5 python multi-index pandas

让我们给出以下带有多索引列的数据框

import numpy as np
import pandas as pd 

a = ['i', 'ii']
b = list('abc')
mi = pd.MultiIndex.from_product([a,b])
df = pd.DataFrame(np.arange(100,100+len(mi)*3).reshape([-1,len(mi)]), 
                  columns=mi)
print(df)
#     i             ii
#     a    b    c    a    b    c
# 0  100  101  102  103  104  105
# 1  106  107  108  109  110  111
# 2  112  113  114  115  116  117
Run Code Online (Sandbox Code Playgroud)

使用.loc[]和我尝试按照该顺序pd.IndexSlice选择列'c'和。'b'

idx = pd.IndexSlice
df.loc[:, idx[:, ['c','b']]]
Run Code Online (Sandbox Code Playgroud)

但是,如果我查看输出,就会发现所请求的顺序不被遵守!

#     i        ii
#     b    c    b    c
# 0  101  102  104  105
# 1  107  108  110  111
# 2  113  114  116  117
Run Code Online (Sandbox Code Playgroud)

这是我的问题:

  1. 为什么 pandas 不保留顺序?我认为这非常危险,因为该列表['c', 'b']意味着从用户角度来看的排序。
  2. loc[]如何在保留顺序的同时访问列?

更新:(2020年2月2日)

该问题已被确定为pandas bug。在修复它的过程中,已经识别了这个相关问题df.loc[:, pd.IndexSlice[:, ['c','b']]],它解决了诸如 之类的表达式的语义歧义。

同时,可以使用已接受的答案中描述的方法来规避该问题。

WeN*_*Ben 4

引用此链接

我认为我们不能保证 .loc 操作返回值的顺序,所以我倾向于说这不是一个错误,但让我们看看其他人怎么说

所以我们应该改用reindex

df.reindex(columns=pd.MultiIndex.from_product([a,['c','b']]))
     i        ii     
     c    b    c    b
0  102  101  105  104
1  108  107  111  110
2  114  113  117  116
Run Code Online (Sandbox Code Playgroud)