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

熊猫:在多索引数据帧中重新索引和插值

  •  0
  • Evan  · 技术社区  · 6 年前

    reindex df ,我想对这些测量值进行重新索引和插值,使它们与其他数据对齐。

    我的实际数据有7个索引级别和几个不同的度量。我希望这个玩具数据问题的解决方案适用于我的真实数据。它是“小数据”;每个单独的测量值为几KB。

    这里有两个玩具问题,一个表现出预期的行为,另一个似乎什么都不做。

    单级索引,按预期工作:

    """
    step,value
    1,1
    3,2
    5,1
    """
    df_i = pd.read_clipboard(sep=",").set_index("step")
    print(df_i)
    
    new_index = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    df_i = df_i.reindex(new_index).interpolate()
    print(df_i)
    

    输出,原始df和重新索引和插值的df:

          value
    step       
    1         1
    3         2
    5         1
          value
    step       
    1       1.0
    2       1.5
    3       2.0
    4       1.5
    5       1.0
    6       1.0
    7       1.0
    8       1.0
    9       1.0
    

    效果很好。

    """
    sample,meas_id,step,value
    1,1,1,1
    1,1,3,2
    1,1,5,1
    1,2,3,2
    1,2,5,2
    1,2,7,1
    1,2,9,0
    """
    df_mi = pd.read_clipboard(sep=",").set_index(["sample", "meas_id", "step"])
    print(df_mi)
    
    df_mi = df_mi.reindex(new_index, level="step").interpolate()
    print(df_mi)
    

    输出,重新索引后不变(因此插值后不变):

                         value
    sample meas_id step       
    1      1       1         1
                   3         2
                   5         1
           2       3         2
                   5         2
                   7         1
                   9         0
    
    
                         value
    sample meas_id step       
    1      1       1         1
                   3         2
                   5         1
           2       3         2
                   5         2
                   7         1
                   9         0
    

    事实上 在多索引df中重新索引列?

    这是我想要的输出,假设线性插值:

                         value
    sample meas_id step       
    1      1       1         1
                   2       1.5
                   3         2
                   5         1
                   6         1
                   7         1
                   8         1
                   9         1
           2       1       NaN (or 2)
                   2       NaN (or 2)
                   3         2
                   4         2
                   5         2
                   6       1.5
                   7         1
                   8       0.5
                   9         0
    

    Fill multi-index Pandas DataFrame with interpolation

    Resampling Within a Pandas MultiIndex

    pandas multiindex dataframe, ND interpolation for missing values

    Fill multi-index Pandas DataFrame with interpolation

    https://pandas.pydata.org/pandas-docs/stable/basics.html#basics-reindexing

    可能与GitHub相关的问题:

    https://github.com/numpy/numpy/issues/11975

    https://github.com/pandas-dev/pandas/issues/23104

    https://github.com/pandas-dev/pandas/issues/17132

    1 回复  |  直到 6 年前
        1
  •  1
  •   BENY    6 年前

    IIUC使用创建索引 MultiIndex.from_product ,那就做吧 reindex

    idx=pd.MultiIndex.from_product([df_mi.index.levels[0],df_mi.index.levels[1],new_index])    
    df_mi.reindex(idx).interpolate()
    Out[161]: 
              value
    1 1 1  1.000000
        2  1.500000
        3  2.000000
        4  1.500000
        5  1.000000
        6  1.142857
        7  1.285714
        8  1.428571
        9  1.571429
      2 1  1.714286 # here is bad , it take previous value into consideration 
        2  1.857143
        3  2.000000
        4  2.000000
        5  2.000000
        6  1.500000
        7  1.000000
        8  0.500000
        9  0.000000
    

    我的想法

    def idx(x):
        idx = pd.MultiIndex.from_product([x.index.get_level_values(0).unique(), x.index.get_level_values(1).unique(), new_index])
        return idx
    
    
    
    pd.concat([y.reindex(idx(y)).interpolate() for _,y in df_mi.groupby(level=[0,1])])
    
           value
    1 1 1    1.0
        2    1.5
        3    2.0
        4    1.5
        5    1.0
        6    1.0
        7    1.0
        8    1.0
        9    1.0
      2 1    NaN
        2    NaN
        3    2.0
        4    2.0
        5    2.0
        6    1.5
        7    1.0
        8    0.5
        9    0.0