如何用Numpy/Pandas实现3D数组的滑动窗口遍历?
生成3D数组的连续滑动窗口:解决尾部随机值问题
问题根源
你手里的(270,5,22)数组是把连续1350天的特征数据拆成了270个不重叠的5天块。直接对这个块数组用as_strided会导致跨块访问超出数组内存范围,这就是尾部出现随机值的原因——你访问到了数组外的未初始化内存。
要生成步长1天的连续滑动窗口(比如01-05、02-06这种),必须先把数组还原成按天连续排列的2D结构,再基于此生成滑动窗口。
Numpy 实现(推荐)
简洁版:用sliding_window_view(Numpy 1.20+)
这是官方推荐的安全方法,不用手动计算步长:
import numpy as np # 第一步:把原3D数组展开成按天排列的2D数组 (1350, 22) daily_data = X_train.reshape(-1, 22) # 第二步:生成滑动窗口,窗口大小5,步长1 slide_windows = np.lib.stride_tricks.sliding_window_view(daily_data, window_shape=(5, 22)) # 最终结果shape是(1346,5,22),1346 = 1350 - 5 + 1 print(slide_windows.shape)
兼容旧版本:手动用as_strided
如果你的Numpy版本低于1.20,可以手动计算步长,但必须严格控制窗口数量避免越界:
import numpy as np # 替换成你的X_train X_train = np.random.rand(270,5,22) # 展开为按天的2D数组 daily_data = X_train.reshape(-1,22) total_days, num_features = daily_data.shape window_size =5 # 计算有效窗口数量:总天数 - 窗口大小 +1 num_windows = total_days - window_size +1 # 获取数组的内存步长 day_stride, feat_stride = daily_data.strides # 构建滑动窗口:每个窗口的步长是一天的内存长度,窗口内每行也是一天的步长 slide_windows = np.lib.stride_tricks.as_strided( daily_data, shape=(num_windows, window_size, num_features), strides=(day_stride, day_stride, feat_stride) ) print(slide_windows.shape)
Pandas 实现
如果习惯用Pandas处理数据,可以先转成DataFrame再用滚动窗口:
import pandas as pd import numpy as np # 1. 展开原数组为按天的DataFrame daily_data = X_train.reshape(-1,22) df = pd.DataFrame(daily_data, columns=[f'feature_{i}' for i in range(22)]) # 2. 遍历滚动窗口,收集完整的5天窗口 slide_windows = [] for window in df.rolling(window=5): if len(window) ==5: # 跳过前4个不足5天的窗口 slide_windows.append(window.values) # 转成numpy数组,最终shape(1346,5,22) slide_windows = np.array(slide_windows)
或者更高效的无循环写法:
# 利用rolling+apply批量生成窗口 slide_windows = df.rolling(window=5).apply( lambda x: x.values.flatten(), raw=True ).dropna().values # 把扁平化的窗口还原成(5,22)的形状 slide_windows = slide_windows.reshape(-1,5,22)
内容的提问来源于stack exchange,提问作者Ruben Guillemyn
相关产品推荐
相关产品推荐

