【问题标题】:Pandas set_levels, how to avoid sorting of labels?Pandas set_levels,如何避免标签排序?
【发布时间】:2018-06-12 04:08:33
【问题描述】:

我在使用多索引的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

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

【问题讨论】:

    标签: python pandas multi-index


    【解决方案1】:

    我不完全理解为什么会发生这种情况,但我找到了导致问题的原因和解决方案:

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

    >>> 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]])
    

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

    >>> 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 会有这种行为。

    【讨论】:

    • 我也很好奇,现在问题出在get_level_values ?.
    • 因为标签的结构方式有效:labels=[[2, 1, 0], [1, 0, 2]]。每次调用时,第二层的第一个和第二个索引都会不断交换。并详细说明您的第一句话:问题在于标签的结构方式(我认为)
    【解决方案2】:

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

    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
    

    【讨论】:

    • 这是一个不错的选择。但我想知道为什么要对其进行排序。
    • @Dark 当你使用 get_level_values 时,你得到了关卡,但是你有多个索引,这意味着标签信息也很重要
    猜你喜欢
    • 2019-06-13
    • 2011-09-07
    • 2021-04-15
    • 2020-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-25
    相关资源
    最近更新 更多