代码之家  ›  专栏  ›  技术社区  ›  piRSquared

在特定级别重新索引熊猫MultiIndex

  •  1
  • piRSquared  · 技术社区  · 10 年前

    安装程序

    import pandas as pd
    import numpy as np
    from string import ascii_lowercase
    
    tidx = pd.date_range(end='2016-04-30', freq='M', periods=3)
    tidx2 = tidx + pd.offsets.MonthBegin(-1) + pd.offsets.Day(15) + pd.offsets.BDay(-1)
    
    np.random.seed([3,1415])
    
    df1 = pd.DataFrame(np.random.rand(9, 1), columns=['Value'],
                       index=pd.MultiIndex.from_product([tidx, list(ascii_lowercase)[:3]]))
    df2 = pd.DataFrame(np.random.rand(9, 1), columns=['Value'],
                       index=pd.MultiIndex.from_product([tidx2, list(ascii_lowercase)[:3]]))
    

    我想重新索引 df2.index.levels[0] 具有 df1.index.levels[0]

    我所做的:

     df1.unstack().reindex(df2.unstack().index, method='ffill').stack()
    

    看起来像:

                     Value
    2016-02-29 a  0.757983
               b  0.934829
               c  0.831104
    2016-03-31 a  0.879891
               b  0.926879
               c  0.721535
    2016-04-30 a  0.117642
               b  0.145906
               c  0.199844
    

    然而,这并不能概括为 MultiIndex 的级别超过2级。

    问题

    一般的方法是什么 reindex 索引的特定级别?

    1 回复  |  直到 9 年前
        1
  •  1
  •   IanS    10 年前

    编辑 :新的解决方案,可能更符合问题的精神:

    def func(dfg):
        return dfg.reset_index(level=1, drop=True).reindex(df1.index.levels[0], method='ffill')
    
    df2.groupby(level=1).apply(func).swaplevel(i=0, j=1).sortlevel(0)
    

    其想法是在像往常一样重新编制索引之前按级别1分组。与前面的解决方案不同,这将执行基于时间的正向填充。

    第二次编辑 :为了概括到多个级别,请替换 level=1 使用:

    level=list(range(1, df2.index.nlevels))
    

    在两个函数调用中。


    上一个答案 :

    我不知道这是否适用于所有情况,但在这种情况下,它会返回您想要的结果:

    df2.index.set_levels(df1.index.get_level_values(0), level=0)
    

    结果:

    In [12]: df2
    Out[12]: 
                     Value
    2016-02-29 a  0.757983
               b  0.934829
               c  0.831104
    2016-03-31 a  0.879891
               b  0.926879
               c  0.721535
    2016-04-30 a  0.117642
               b  0.145906
               c  0.199844