pandas resample: 强制时间条的特定开始时间

pandas resample: forcing specific start time of time bars

我有一些时间序列 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   ****
...

感谢您的帮助!

您可以将 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

.resample 有点像通配符。它与 datetime64[ns]timedelta64[ns] 的行为截然不同,所以我个人认为在做 .sum.first 之类的事情时使用 groupby 更可靠。 =28=]

示例数据

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] 时,它将重新采样到 "round" 个箱子:

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]

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 得到的结果相同,它被分到 "round" 分箱。

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

例如截断第一次(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()将使用这个时间作为起点(9:00在OP的情况下)。

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