【问题标题】:Resampling with start and end date columns使用开始和结束日期列重新采样
【发布时间】:2015-11-26 14:43:28
【问题描述】:

我有一个如下所示的数据框:

 START_TIME   END_TIME     TRIAL_No        itemnr
 2403950      2413067      Trial: 1        P14
 2413378      2422499      Trial: 2        P03
 2422814      2431931      Trial: 3        P13
 2432246      2441363      Trial: 4        P02
 2523540      2541257      Trial: 5        P11
 2541864      2560297      Trial: 6        P10
 2560916      2577249      Trial: 7        P05

桌子就这样继续下去。 START_TIME 和 END_TIME 都以毫秒为单位,它们是试验的开始和结束时间。所以我想要做的是,我想将 START_TIME 重新采样为 100 毫秒 bin itme,并在每个 START_TIME 和 END_TIME 之间插入变量(TRIAL_No 和 itemnr)。在这些区域之外,这些变量的值应为“NA”。例如,对于第一行,START_TIME 是 2403950,END_TIME 是 2413067。它们之间的差异是 9117 毫秒。所以“试用:1”停留了 9117 毫秒,这大约是 91 个 bin 时间,因为每个 bin 时间相隔 100 毫秒。所以我想在结果数据框中重复“Trial_1”和“P14”91次。其余的也是如此。如下所示:

Bin_time     TRIAL_No    itemnr
2403950      Trial: 1    P14
2404050      Trial: 1    P14
2404150      Trial: 1    P14
            ...
2413050      Trial: 1    P14
2413150      Trial: 2    P03
2413250      Trial: 2    P03

等等。我不确定是否可以直接在 pandas 中使用,或者是否需要进行一些预处理。

【问题讨论】:

    标签: python python-2.7 pandas dataframe


    【解决方案1】:

    通过concat 数据框创建新数据框后,我可以按行对其进行分组,并将resample 应用于每个组(使用ffill 方法进行前向填充)。

    print df
    #   START_TIME  END_TIME  TRIAL_No itemnr
    #0     2403950   2413067  Trial: 1    P14
    #1     2413378   2422499  Trial: 2    P03
    #2     2422814   2431931  Trial: 3    P13
    #3     2432246   2441363  Trial: 4    P02
    #4     2523540   2541257  Trial: 5    P11
    #5     2541864   2560297  Trial: 6    P10
    #6     2560916   2577249  Trial: 7    P05
    
    #PREDPROCESSING
    #helper column for matching start and end rows
    df['row'] = range(len(df))
    
    #reshape to df - every row two times repeated for each date of START_TIME and END_TIME
    starts = df[['START_TIME','TRIAL_No','itemnr','row']].rename(columns={'START_TIME':'Bin_time'})
    ends = df[['END_TIME','TRIAL_No','itemnr','row']].rename(columns={'END_TIME':'Bin_time'})
    df = pd.concat([starts, ends])
    df = df.set_index('row', drop=True)
    df = df.sort_index()
    
    #convert miliseconds to timedelta for resampling by time 100ms
    df['Bin_time'] = df['Bin_time'].astype('timedelta64[ms]')
    
    print df
    #           Bin_time  TRIAL_No itemnr
    #row                                 
    #0   00:40:03.950000  Trial: 1    P14
    #0   00:40:13.067000  Trial: 1    P14
    #1   00:40:13.378000  Trial: 2    P03
    #1   00:40:22.499000  Trial: 2    P03
    #2   00:40:22.814000  Trial: 3    P13
    #2   00:40:31.931000  Trial: 3    P13
    #3   00:40:32.246000  Trial: 4    P02
    #3   00:40:41.363000  Trial: 4    P02
    #4   00:42:03.540000  Trial: 5    P11
    #4   00:42:21.257000  Trial: 5    P11
    #5   00:42:21.864000  Trial: 6    P10
    #5   00:42:40.297000  Trial: 6    P10
    #6   00:42:40.916000  Trial: 7    P05
    #6   00:42:57.249000  Trial: 7    P05
    
    print df.dtypes
    #Bin_time    timedelta64[ms]
    #TRIAL_No             object
    #itemnr               object
    #dtype: object
    
    #resample and fill missing data 
    df = df.groupby(df.index).apply(lambda x: x.set_index('Bin_time').resample('100ms',how='first',fill_method='ffill'))
    
    df = df.reset_index()
    df = df.drop(['row'], axis=1)
    
    #convert timedelta to integer back
    df['Bin_time'] = (df['Bin_time'] / np.timedelta64(1, 'ms')).astype(int)
    
    print df.head()
    #  Bin_time  TRIAL_No itemnr
    #0  2403950  Trial: 1    P14
    #1  2404050  Trial: 1    P14
    #2  2404150  Trial: 1    P14
    #3  2404250  Trial: 1    P14
    #4  2404350  Trial: 1    P14
    

    编辑:

    如果您想在群组之外获取NaN,您可以在groupby之后更改代码:

    #resample and fill missing data 
    df = df.groupby(df.index).apply(lambda x: x.set_index('Bin_time').resample('100ms', how='first',fill_method='ffill'))
    
    #reset only first level - drop index row
    df = df.reset_index(level=0, drop=True)
    #resample by 100ms, outside are NaN
    df = df.resample('100ms', how='first')
    df = df.reset_index()
    #convert timedelta to integer back
    df['Bin_time'] = (df['Bin_time'] / np.timedelta64(1, 'ms')).astype(int)
    
    print df
    

    【讨论】:

    • 谢谢。有效。我在另一个线程中有另一个问题,但似乎没有人回答我。所以如果你有时间,你可以看看它。这是link
    • 我确实接受了。别忘了看我的另一个问题。这是link
    • 另一个答案已经完成,如果我理解正确,请检查它。谢谢。
    • 我仔细检查了这个答案的输出,我看到每个开始和结束时间都在他们自己的组中分组和重新采样。但是是否有可能进入 bin 时间相隔 100 毫秒。区域外其他列的值为“NA”?
    • 完美。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2018-02-05
    • 1970-01-01
    • 2020-09-29
    • 2019-07-29
    • 2021-09-29
    • 2021-12-28
    • 2023-03-17
    • 2012-08-19
    相关资源
    最近更新 更多