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

pandas中水平独立于每行的插值

  •  1
  • user96564  · 技术社区  · 8 年前

    我有一个这样的数据框

    ID,Time0,Sum0,Average0,Time1,Sum1,Average1
    1,1520320347531.0,59.3635,18.2828,1520324772351.0,59.5031,18.4745
    1,1519860442638.0,60.1159,20.3027,1519861181524.0,60.1033,20.31705
    

    我想每5分钟做一次水平插值。

    如果数据是垂直排列的,那么这段代码可以很好地进行插值,但是我不确定如何对这些行进行水平插值。即使在两个不同的行中有相同的id,我想使interpolate独立于每一行。

    df = df.set_index(['Time'])
    df.index = pd.to_datetime(df.index, unit='ms')
    
    df = (df.groupby('ID')[['Sum', 'Average']]
           .resample('5min')
           .mean()
           .groupby(level=0)
           .apply(lambda x: x.interpolate()).reset_index())
    

    有什么建议吗?

    1 回复  |  直到 8 年前
        1
  •  1
  •   Ben.T    8 年前

    我有一个答案,但有点难看,对任何一个过度操纵数据的人来说,请随意更正。

    首先,根据你的数据,我改变了 1520324772351.0 (第一行,第1列)到 1520321086417.0 ,否则会超过10分钟,并以多个列为例。

    从您的数据中,我首先创建一个连接的数据帧,如

    df_concat = (pd.concat([df[['ID','Time0','Sum0','Average0']]
                                    .rename(columns={'Time0':'Time','Sum0':'Sum','Average0':'Average'}),
                           df[['ID','Time1','Sum1','Average1']]
                                    .rename(columns={'Time1':'Time','Sum1':'Sum','Average1':'Average'})])
                        .sort_index())
    

    要获取这样的数据:

       ID          Time      Sum   Average
    0   1  1.520320e+12  59.3635  18.28280
    0   1  1.520321e+12  59.5031  18.47450
    1   1  1.519860e+12  60.1159  20.30270
    1   1  1.519861e+12  60.1033  20.31705
    

    在这里,您可以使用方法处理索引列上具有groupby的列中的数据:

    df_concat_set = df_concat.reset_index().set_index(['Time'])
    df_concat_set.index = pd.to_datetime(df_concat_set.index, unit='ms')
    
    df_concat_set = (df_concat_set.groupby('index')[['Sum', 'Average']]
                                  .resample('5min')
                                  .mean()
                                  .groupby(level=0)
                                  .apply(lambda x: x.interpolate())
                                  .reset_index())
    

    这里有数据:

       index                Time      Sum    Average
    0      0 2018-03-06 07:10:00  59.3635  18.282800
    1      0 2018-03-06 07:15:00  59.4333  18.378650
    2      0 2018-03-06 07:20:00  59.5031  18.474500
    3      1 2018-02-28 23:25:00  60.1159  20.302700
    4      1 2018-02-28 23:30:00  60.1096  20.309875
    5      1 2018-02-28 23:35:00  60.1033  20.317050
    

    为了把它放回行,我这样做了(这里我确定有一个pivot_table方法我不知道,但这种方法有效):

    #first create a column with incremental number within a group of index:
    df_concat_set['level_1'] = df_concat_set.groupby('index').cumcount()+1
    # then set index and unstack
    df_unstack = df_concat_set.set_index(['index','level_1']).unstack(level=1)
    # here you have multiindex columns so change it to one level:
    df_unstack.columns = [col[0]+str(col[1]-1) for col in df_unstack.columns]
    # then change the order of columns (if necessary)
    df_unstack = df_unstack[[ s+str(i) for i in range(len(df_unstack.columns)/3) 
                                            for s in ['Time','Sum','Average'] ]]
    

    您的最终输出是:

                        Time0     Sum0  Average0               Time1     Sum1  \
    index                                                                       
    0     2018-03-06 07:10:00  59.3635   18.2828 2018-03-06 07:15:00  59.4333   
    1     2018-02-28 23:25:00  60.1159   20.3027 2018-02-28 23:30:00  60.1096   
    
            Average1               Time2     Sum2  Average2  
    index                                                    
    0      18.378650 2018-03-06 07:20:00  59.5031  18.47450  
    1      20.309875 2018-02-28 23:35:00  60.1033  20.31705 
    

    这就是我希望你想要的。

    正如我所说,这是过度操纵,但我找不到其他方法。