Pandas如何按1分钟重采样DataFrame并应用10分钟窗口自定义函数?
场景与需求
- 已实现入参为数组的自定义计算函数
custom_f - 现有DataFrame以非严格对齐整分钟的时间戳为索引,索引示例:
2022-05-12 00:01:03 2022-05-12 00:03:17 2022-05-12 00:06:10
- 需要重采样得到右标签、整分钟对齐的结果,目标索引示例:
2022-05-12 00:02:00 2022-05-12 00:03:00 2022-05-12 00:04:00 2022-05-12 00:05:00 2022-05-12 00:06:00 2022-05-12 00:07:00
- 已尝试的基础重采样代码:
df.resample('1min', label='right', closed='right').apply(lambda x: custom_f(x))
该方案的缺陷是自定义函数仅能接收最近1分钟内的数据,实际要求为每个输出时间点的计算需覆盖该点往前10分钟的全量窗口数据:例如输出2022-05-12 00:07:00对应的结果时,入参需要包含2022-05-11 23:57:00及之后的所有行数据。
- 曾考虑通过10次循环、每次修改重采样原点后拼接结果的实现方式,但代码冗余、执行效率低,需要更优解法。
最优实现方案
不需要写循环拼接,直接使用pandas原生的时间滚动窗口搭配重采样即可实现,底层为向量化计算,性能远高于循环方案,代码如下:
# 第一步:先做1分钟粒度重采样,补全缺失的整分钟索引,保证时间轴连续 df_1min = df.resample('1min', label='right', closed='right').asfreq() # 第二步:配置10分钟右闭滚动窗口,对每个窗口传入自定义函数计算 result = df_1min.rolling('10min', closed='right').apply(custom_f)
如果不需要保留无原始数据的空分钟对应的空结果,计算完成后调用result.dropna()即可。
逻辑校验:该实现完全匹配需求,每个整分钟输出点对应的滚动窗口,会自动截取该时间点往前10分钟(包含当前时间点)的所有有效数据传入函数,完全符合举例的
00:07:00对应取前一日23:57:00之后所有数据的规则。
如果自定义函数需要接收数组格式入参、不支持滚动窗口默认的序列传参,可以调整传参逻辑:
result = ( df.resample('1min', label='right', closed='right') .asfreq() .rolling('10min', closed='right') .apply(lambda window_data: custom_f(window_data.values)) )
内容的提问来源于stack exchange,提问作者questionsguy
相关产品推荐
相关产品推荐

