如何用Pandas的resample实现ceil分组重采样效果?
问题描述
需要对时间戳字段重采样,使用Pandas的resample方法未得到预期结果,目前groupby结合ceil的方式符合需求,尝试调整resample的closed和convention参数未果,询问能否仅用resample实现相同效果。
原代码与结果
代码示例
import pandas as pd import numpy as np periods = 12 df = pd.DataFrame({ 'datetime': pd.date_range('2020-01-01 00:45:00', freq='15T', periods=periods), 'value': np.random.randint(1, 10, periods), }) df['datetime_ceil'] = df['datetime'].dt.ceil('H') display(df) df_agg_resample = df[['datetime', 'value']].resample('H', on='datetime').sum().reset_index().rename(columns={'datetime': 'datetime_resample'}).shift(-1) df_agg_ceil = df[['datetime_ceil', 'value']].groupby('datetime_ceil').sum().reset_index() df_agg = pd.concat([df_agg_resample, df_agg_ceil], axis=1) df_agg
结果示例
datetime value datetime_ceil 0 2020-01-01 00:45:00 2 2020-01-01 01:00:00 1 2020-01-01 01:00:00 3 2020-01-01 01:00:00 2 2020-01-01 01:15:00 1 2020-01-01 02:00:00 3 2020-01-01 01:30:00 5 2020-01-01 02:00:00 4 2020-01-01 01:45:00 2 2020-01-01 02:00:00 5 2020-01-01 02:00:00 7 2020-01-01 02:00:00 6 2020-01-01 02:15:00 7 2020-01-01 03:00:00 7 2020-01-01 02:30:00 6 2020-01-01 03:00:00 8 2020-01-01 02:45:00 4 2020-01-01 03:00:00 9 2020-01-01 03:00:00 1 2020-01-01 03:00:00 10 2020-01-01 03:15:00 2 2020-01-01 04:00:00 11 2020-01-01 03:30:00 3 2020-01-01 04:00:00 datetime_resample value datetime_ceil value 0 2020-01-01 01:00:00 11.0 2020-01-01 01:00:00 5 1 2020-01-01 02:00:00 24.0 2020-01-01 02:00:00 15 2 2020-01-01 03:00:00 6.0 2020-01-01 03:00:00 18 3 NaT NaN 2020-01-01 04:00:00 5
解决方案
可以通过调整resample的closed和label参数实现与groupby+ceil完全一致的效果,无需额外的shift操作:
修改后的resample代码
df_agg_resample = df[['datetime', 'value']].resample( 'H', on='datetime', closed='right', label='right' ).sum().reset_index().rename(columns={'datetime': 'datetime_resample'})
参数说明
closed='right':指定重采样区间的右边界为闭合状态,例如小时区间为(00:00, 01:00],包含01:00这个时间点,不包含00:00。这保证了01:00的记录会被归入当前区间,而不是下一个区间。label='right':用区间的右边界作为结果的时间标签,也就是把(00:00, 01:00]区间的聚合结果标记为01:00,这与dt.ceil('H')得到的分组键完全匹配。
验证结果
修改后df_agg_resample的输出将和df_agg_ceil完全一致:
2020-01-01 01:00:00对应的sum值为2+3=52020-01-01 02:00:00对应的sum值为1+5+2+7=152020-01-01 03:00:00对应的sum值为7+6+4+1=182020-01-01 04:00:00对应的sum值为2+3=5
内容的提问来源于stack exchange,提问作者Augusto Fonseca
相关产品推荐
相关产品推荐

