【问题标题】:How to change single index value in level 1 in MultiIndex dataframe?如何更改 MultiIndex 数据帧中级别 1 的单个索引值?
【发布时间】:2020-11-29 23:18:46
【问题描述】:

我有这个 MultiIndex 数据框,df 在使用正则表达式解析一些日期的文本列之后。

df.columns
Index(['all', 'month', 'day', 'year'], dtype='object')
        all   month day year
  match             
456 0   2000    1   1   2000
461 0   16      1   1   16
    1   1991    1   1   1991
463 0   25      1   1   25
    1   2014    1   1   2014
465 0   19      1   1   19
    1   1976    1   1   1976
477 0   14      1   1   14
    1   1994    1   1   1994
489 0   35      1   1   35
    1   1985    1   1   1985

我只需要保留年份 (2000,1991,2014,1976,1994,1985) 的行。除了第一个 (456,0) 之外,其中大多数在 1 级索引为 1。 这样我就可以这样处理它们:

df=df.drop(index=0, level=1)

我的结果应该是这样的。

        all   month day year
  match             
456 0   2000    1   1   2000
461 1   1991    1   1   1991
463 1   2014    1   1   2014
465 1   1976    1   1   1976
477 1   1994    1   1   1994
489 1   1985    1   1   1985

我试过了

df.rename(index={(456,0):(456,1)}, level=1, inplace=True)

它似乎没有做任何事情。

我可以做 df1=df.drop((456,1)) 和 df2=df.drop(index=0, level=1) 然后连接它们并删除重复项,但这似乎不是很有效?

我不能删除 MultiIndex,因为稍后我需要将此子集附加到更大的数据帧。 谢谢。

【问题讨论】:

    标签: python-3.x pandas rename multi-index


    【解决方案1】:

    第一个想法是| 按位链接 2 个掩码 OR

    df = df[(df.index.get_level_values(1) == 1) | (df.index.get_level_values(0) == 456)]
    print (df)
            all  month  day  year
    456 0  2000      1    1  2000
    461 1  1991      1    1  1991
    463 1  2014      1    1  2014
    465 1  1976      1    1  1976
    477 1  1994      1    1  1994
    489 1  1985      1    1  1985
    

    如果需要总是第一个值的另一个想法是可以通过索引设置数组掩码到True

    mask = df.index.get_level_values(1) == 1
    mask[0] = True
    
    df = df[mask]
    print (df)
            all  month  day  year
    456 0  2000      1    1  2000
    461 1  1991      1    1  1991
    463 1  2014      1    1  2014
    465 1  1976      1    1  1976
    477 1  1994      1    1  1994
    489 1  1985      1    1  1985
    

    另一个开箱即用的解决方案是通过 Index.duplicated 过滤不重复的值,在这里工作是因为第一个值 456 是唯一的,并且对于所有其他值都需要第二行:

    df1 = df[~df.index.get_level_values(0).duplicated(keep='last')]
    print (df1)
            all  month  day  year
    456 0  2000      1    1  2000
    461 1  1991      1    1  1991
    463 1  2014      1    1  2014
    465 1  1976      1    1  1976
    477 1  1994      1    1  1994
    489 1  1985      1    1  1985
    

    【讨论】:

    • @Manakin - isin 不能在这里使用,因为测试了第一级和第二级:(
    • @jezrael 刚刚测试过,你是对的!那很奇怪!我以为每个记录集都会专门过滤
    【解决方案2】:

    另一种方式。查询等级

    df.query('match == [1]')
    
    
    
     match   all  month  day  year
    461      1  1991      1    1  1991
    463      1  2014      1    1  2014
    465      1  1976      1    1  1976
    477      1  1994      1    1  1994
    489      1  1985      1    1  1985
    

    【讨论】:

      猜你喜欢
      • 2023-03-20
      • 2018-06-19
      • 1970-01-01
      • 2019-04-16
      • 2020-04-15
      • 1970-01-01
      • 2016-11-28
      • 1970-01-01
      相关资源
      最近更新 更多