如何高效从数组及400k行DataFrame生成滑动窗口数组?
高效生成滑动窗口数组的优化方案
嘿,针对你处理400k行DataFrame时,纯Python循环生成滑动窗口速度拉胯的问题,我给你几个矢量化/编译级的高效方案,绝对能大幅提升处理速度:
1. 用NumPy的内存视图秒生成窗口(最快方案)
NumPy的stride_tricks.as_strided可以直接利用数组的内存布局生成滑动窗口,完全不需要循环,相当于“零拷贝”生成结果,速度快到离谱。
示例代码:
import numpy as np # 如果你是处理DataFrame列,先转成NumPy数组:df['your_col'].values input_arr = np.array([0, 1, 2, 3, 4, 5, 6]) window_size = 3 num_windows = len(input_arr) - window_size + 1 # 生成滑动窗口视图 sliding_windows = np.lib.stride_tricks.as_strided( input_arr, shape=(num_windows, window_size), strides=(input_arr.strides[0], input_arr.strides[0]) ) print(sliding_windows) # 输出: # [[0 1 2] # [1 2 3] # [2 3 4] # [3 4 5] # [4 5 6]]
⚠️ 注意:这个方法生成的是原数组的视图,不是副本。如果后续需要修改窗口里的元素,记得用.copy()生成独立数组,不然会不小心改到原数据。
2. 直接在Pandas里用rolling处理(适配DataFlow工作流)
如果你不想跳出Pandas的工作流,用rolling结合矢量化的apply也能搞定,关键是要开raw=True参数,让它直接传NumPy数组给lambda,避免Series的额外开销:
import pandas as pd df = pd.DataFrame({'data': [0, 1, 2, 3, 4, 5, 6]}) window_size = 3 # 生成滑动窗口列 df['sliding_window'] = df['data'].rolling(window=window_size).apply( lambda x: x.tolist(), raw=True # 这个参数是提速关键! ) # 去掉前window_size-1个不完整的窗口行 result = df.dropna()['sliding_window'].tolist() print(result) # 输出:[[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]]
3. 用Numba编译你的循环(灵活又高效)
如果你的窗口逻辑比较复杂(比如不是简单取连续元素),纯矢量化不好实现,那可以用Numba把你的Python循环编译成机器码,速度能接近C语言:
from numba import jit import numpy as np @jit(nopython=True) # 开启无Python模式编译,速度拉满 def sliding_window_numba(arr, window_size): num_windows = len(arr) - window_size + 1 # 提前分配好内存,避免动态扩容 result = np.empty((num_windows, window_size), dtype=arr.dtype) for i in range(num_windows): result[i] = arr[i:i+window_size] return result input_arr = np.array([0, 1, 2, 3, 4, 5, 6]) print(sliding_window_numba(input_arr, 3))
第一次运行会有几秒的编译时间,但之后每次调用都超快,适合需要重复生成窗口的场景。
性能小总结
针对400k行的数据集:
- NumPy stride_tricks速度第一,完全无循环,直接操作内存;
- Numba编译版紧随其后,适合复杂逻辑;
- Pandas rolling速度稍慢胜在便捷,适配你的DataFrame工作流。
内容的提问来源于stack exchange,提问作者trust512
相关产品推荐
相关产品推荐

