【问题标题】:pandas resample: forcing specific start time of time barspandas resample:强制时间条的特定开始时间
【发布时间】:2019-05-07 05:06:10
【问题描述】:

我有一些时间序列 data (pandas.DataFrame),我在 '600S' 条中重新采样:

import numpy as np
data.resample('600S', level='time').aggregate({'abc':np.sum})

我得到这样的东西:

                   abc
time                
09:30:01.446000  19836
09:40:01.446000   8577
09:50:01.446000  29746
10:00:01.446000  29340
10:10:01.446000   5197
...

如何强制时间条从 09:30:00.000000 开始,而不是从数据第一行的时间开始? IE。输出应该是这样的:

                   abc
time                
09:30:00.000000  *****
09:40:00.000000   ****
09:50:00.000000  *****
10:00:00.000000  *****
10:10:00.000000   ****
...

感谢您的帮助!

【问题讨论】:

    标签: python pandas dataframe resampling


    【解决方案1】:

    您可以将Series.dt.floor 添加到您的代码中:

    df.time = df.time.dt.floor('10 min')
    
                  time    abc
    0 2018-12-05 09:30:00  19836
    1 2018-12-05 09:40:00   8577
    2 2018-12-05 09:50:00  29746
    3 2018-12-05 10:00:00  29340
    4 2018-12-05 10:10:00   5197
    

    【讨论】:

    • 四舍五入不行,比如09:30:01和09:40:02,以前属于两个不同的组,现在是一组,
    • 同意 W-B。您需要在 groupby 中使用它而不是重新采样:df.groupby(df.time.dt.floor('10min')).abc.sum()
    • 同意,但是我们的想法是在 resampleaggregation 已经完成之后添加它
    • 如果在重新采样完成之前应用于原始数据并使用 groupby 而不是重新采样(如@ALollz 建议的那样),则它可以工作。
    【解决方案2】:

    .resample 有点像通配符。它与datetime64[ns]timedelta64[ns] 的行为完全不同,因此我个人认为在执行.sum.first 之类的操作时使用groupby 更可靠。

    样本数据

    import pandas as pd
    import numpy as np
    
    n = 1000
    np.random.seed(123)
    df = pd.DataFrame({'time': pd.date_range('2018-01-01 01:13:43', '2018-01-01 23:59:59', periods=n),
                       'abc': np.random.randint(1,1000,n)})
    

    dtypedatetime64[ns] 时,它将重新采样到“圆形”箱:

    df.dtypes
    #time    datetime64[ns]
    #abc              int32
    #dtype: object
    
    df.set_index('time').resample('600S').sum()
                          abc
    time                     
    2018-01-01 01:10:00  2572
    2018-01-01 01:20:00  2257
    2018-01-01 01:30:00  2470
    2018-01-01 01:40:00  3131
    2018-01-01 01:50:00  3402
    

    使用timedelta64[ns],它会根据您的第一次观察开始垃圾箱:

    df['time'] = pd.to_timedelta(df.time.dt.time.astype('str'))
    df.dtypes
    #time    timedelta64[ns]
    #abc               int32
    #dtype: object
    
    df.set_index('time').resample('600S').sum()
               abc
    time          
    01:13:43  3432
    01:23:43  2447
    01:33:43  2588
    01:43:43  3202
    01:53:43  2547
    

    因此,对于timedelta64[ns] 列,我建议您使用groupby.dt.floor 创建垃圾箱,以创建从[XX:00:00 - XX:10:00] 开始的10 分钟垃圾箱

    df.groupby(df.time.dt.floor('600S')).sum()
    #           abc
    #time          
    #01:10:00  2572
    #01:20:00  2257
    #01:30:00  2470
    #01:40:00  3131
    #01:50:00  3402
    

    这与我们在第一种情况下使用datetime64[ns] dtype 得到的结果相同,它被分箱到“圆形”箱中。

    【讨论】:

      【解决方案3】:

      如果您的用例对它很健壮,并且您想延长时间实际开始时间之前,一个解决方案是在开始时间添加一个空行你想要的。

      例如将第一次(df.loc[0] 如果索引已排序,否则将df.index.min())截断为小时(.floor("h")):

      df.loc[df.index.min().floor("h")] = None
      df.sort_index(inplace=True) # cleaner, but not even needed
      

      然后resample() 将使用此时间作为起点(在 OP 的情况下为9:00)。

      这也可用于在数据集实际结束后延长时间范围。

      【讨论】:

        猜你喜欢
        • 2022-12-08
        • 2016-03-13
        • 2019-02-21
        • 2020-10-28
        • 1970-01-01
        • 2018-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多