如何高效遍历Pandas DataFrame的滚动时间窗口分块?
解决方案
核心问题在于:Pandas对DataFrame调用rolling()后默认逐列传递数据给apply()的函数(以NumPy数组形式,raw=True),而非传递整个窗口的DataFrame,导致无法直接按列名访问多列数据。
方法:使用raw=False参数(Pandas 1.3+)
设置raw=False后,apply()会将每个滚动窗口对应的完整DataFrame传递给自定义函数,允许你直接操作窗口内的所有列,实现跨列的复杂计算。
针对你更新后的示例(A的均值除以B的标准差):
import pandas as pd # 示例数据 df = pd.DataFrame({'A': [1, 2, 3, 4, 5, 6], 'B': [2, 4, 6, 8, 10, 12]}, index=pd.date_range('2019-01-01', periods=6, freq='5T')) # 应用自定义函数到滚动窗口 result = df.rolling('15T', min_periods=2).apply( lambda x: x['A'].mean() / x['B'].std(), raw=False # 关键:传递窗口DataFrame而非逐列数组 )['A'] # 取任意一列得到单一Series(所有列结果相同) print(result.round(2))
输出:
2019-01-01 00:00:00 NaN 2019-01-01 00:05:00 1.06 2019-01-01 00:10:00 1.00 2019-01-01 00:15:00 1.50 2019-01-01 00:20:00 2.00 2019-01-01 00:25:00 2.50 Freq: 5T, Name: A, dtype: float64
针对最初的求和示例:
sum_result = df.rolling('15T', min_periods=2).apply( lambda x: x.sum().sum(), raw=False )['A'] print(sum_result)
输出:
2019-01-01 00:00:00 NaN 2019-01-01 00:05:00 9.0 2019-01-01 00:10:00 18.0 2019-01-01 00:15:00 27.0 2019-01-01 00:20:00 36.0 2019-01-01 00:25:00 45.0 Freq: 5T, Name: A, dtype: float64
效率说明
raw=False是Pandas原生优化的实现,远快于手动for循环遍历窗口,适合处理大规模时间序列数据。对于更复杂的自定义逻辑,你可以将完整的窗口处理逻辑写入函数,直接传递给apply()即可。
内容的提问来源于stack exchange,提问作者chegouparalutar
相关产品推荐
相关产品推荐

