【问题标题】:How to remove levels from a multi-indexed dataframe?如何从多索引数据框中删除级别?
【发布时间】:2013-06-09 16:36:01
【问题描述】:

例如,我有:

In [1]: df = pd.DataFrame([8, 9],
                          index=pd.MultiIndex.from_tuples([(1, 1, 1),
                                                           (1, 3, 2)]),
                          columns=['A'])

In [2] df
Out[2]: 
       A
1 1 1  8
  3 2  9

有没有比这更好的方法从索引中删除最后一级:

In [3]: pd.DataFrame(df.values,
                     index=df.index.droplevel(2),
                     columns=df.columns)
Out[3]: 
     A
1 1  8
  3  9

【问题讨论】:

    标签: pandas dataframe multi-index


    【解决方案1】:

    您无需创建新的 DataFrame 实例!可以修改索引:

    df.index = df.index.droplevel(2)
    df
    
         A
    1 1  8
      3  9
    

    您还可以指定负索引,以便从末尾选择:

    df.index = df.index.droplevel(-1)
    

    【讨论】:

    • 这可以应用于 pandas v 0.23+ 的列吗?
    • 我刚刚尝试使用 v 0.22 并为列工作。我比接受的答案更喜欢这个答案。它对我来说更清楚,也可以应用于列。
    【解决方案2】:
    df.reset_index(level=2, drop=True)
    Out[29]: 
         A
    1 1  8
      3  9
    

    【讨论】:

    • 值得注意的是,有一个 inplace 参数,即 True 会修改 df 而不是返回一个新的 DataFrame。
    • 现在可以使用,即使在 pd.Series 中也是如此。 .index.drop(...) 的想法可能已经过时了。
    • 如果您的索引级别 1 是可挖掘的,而不仅仅是完美的数字范围,您是否也会重置级别 1?
    【解决方案3】:

    如果您的索引具有类似

    的名称
           A
    X Y Z
    1 1 1  8
      3 2  9
    

    那么你也可以通过指定索引名来移除

    df.index = df.index.droplevel(Z)

    【讨论】:

      【解决方案4】:

      从0.24+,我们可以直接dropleveldf。因此,要删除索引的最后一级:

      >>> df
      
               col
      1 5 1 4  foo
        3 2 8  bar
      2 4 3 7  saz
      
      # `axis` defaults to `index` or equivalently 0
      
      >>> df.droplevel(-1, axis="index")
      
             col
      1 5 1  foo
        3 2  bar
      2 4 3  saz
      

      水平下降的轴也可以用axis参数控制,默认为0,即超过索引。通过提供一个列表可以一次删除多个级别,如果任何索引有名称,也可以使用这些名称(如链接文档中所示)。


      注意:droplevel 的参数首先尝试被解释为一个标签;因此,如果任何级别碰巧有一个整数名称,它将被删除,即不是位置:

      >>> df
                       col
      this -1 other 0
      1    5  1     4  foo
           3  2     8  bar
      2    4  3     7  saz
      
      
      # literally drops `-1` level
      >>> df.droplevel(-1)
      
                    col
      this other 0
      1    1     4  foo
           2     8  bar
      2    3     7  saz
      
      # literally level `0` is dropped
      >>> df.droplevel(0)
      
                     col
      this -1 other
      1    5  1      foo
           3  2      bar
      2    4  3      saz
      

      为了确保发生位置下降,我们可以使用names 属性并在那里选择位置:

      >>> df
                       col
      this -1 other 0
      1    5  1     4  foo
           3  2     8  bar
      2    4  3     7  saz
      
      # go get the name of the last level, drop whatever it is
      >>> df.droplevel(df.index.names[-1])
      
                     col
      this -1 other
      1    5  1      foo
           3  2      bar
      2    4  3      saz
      
      # similarly...
      >>> df.droplevel(df.index.names[0])
      
                  col
      -1 other 0
      5  1     4  foo
      3  2     8  bar
      4  3     7  saz
      
      

      最后,droplevel 返回一个新的数据帧,所以需要df = df.droplevel(...) 才能看到df 的变化。

      【讨论】:

        猜你喜欢
        • 2021-12-05
        • 1970-01-01
        • 2019-08-24
        • 2020-02-26
        • 2023-04-02
        相关资源
        最近更新 更多