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)})
当 dtype
为 datetime64[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的情况下)。
这也可以用于延长时间范围在数据集的实际结束之后。
我有一些时间序列 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)})
当 dtype
为 datetime64[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的情况下)。
这也可以用于延长时间范围在数据集的实际结束之后。