Pandas set_levels,如何避免标签排序?

Pandas set_levels, how to avoid sorting of labels?

我在使用多索引

set_levels 时遇到问题
from io import StringIO

txt = '''Name,Height,Age
"",Metres,""
A,-1,25
B,95,-1'''

df = pd.read_csv(StringIO(txt),header=[0,1],na_values=['-1',''])

df.columns = df.columns.set_levels(df.columns.get_level_values(level=1).str.replace('Un.*',''),level=1)

     Name Height   Age
   Metres             
0      A    NaN  25.0
1      B   95.0   NaN

如果我运行再次执行相同的命令

df.columns = df.columns.set_levels(df.columns.get_level_values(level=1).str.replace('Un.*',''),level=1)

  Name Height   Age
       Metres      
0    A    NaN  25.0
1    B   95.0   NaN

现在这产生了预期的结果。为什么会出现这种行为?是否可以在第一次尝试时保持标签未排序?

我不完全明白为什么会这样,但我找到了导致问题的原因和解决方案:

如果我们查看列标签,我们会发现一些奇怪的东西

>>> df = pd.read_csv(StringIO(txt),header=[0,1],na_values=['-1',''])
>>> df.columns
MultiIndex(levels=[['Age', 'Height', 'Name'], ['Metres', 'Unnamed: 0_level_1', 'Unnamed: 2_level_1']],
           labels=[[2, 1, 0], [1, 0, 2]])

第二层的索引与第一层的索引不匹配。当您替换字符串时,您会在 correct 顺序中的数组上执行此操作:

>>> df.columns.get_level_values(level=1)
Index(['Unnamed: 0_level_1', 'Metres', 'Unnamed: 2_level_1'], dtype='object')

但是你可以通过索引得到不正确顺序的数组:

>>> df.columns.levels[1]
Index(['Metres', 'Unnamed: 0_level_1', 'Unnamed: 2_level_1'], dtype='object')

所以要删除未命名的索引:

>>> df.columns = df.columns.set_levels(df.columns.levels[1].str.replace('Un.*', ''), level=1)
>>> df

  Name Height   Age
       Metres
0    A    NaN  25.0
1    B   95.0   NaN

但是我希望有人指出为什么使用 get_set_levels 会出现这种行为。

听起来您需要,这将根据您的原始结构进行修改

df.rename(columns=lambda x : '' if 'Unnamed' in x else x , level=1)
Out[106]: 
  Name Height   Age
       Metres      
0    A    NaN  25.0
1    B   95.0   NaN