Python无循环构建含历史状态的多变量时间序列特征向量
无循环实现多变量时间序列滞后特征构造
嘿,这个需求我太熟了!要给多变量时间序列构造包含当前时刻和l个历史时刻的特征向量,完全不用写循环,用Numpy或者Pandas的内置矢量化操作就能高效搞定,而且速度比循环快得多~
方法一:Numpy 滑动窗口(推荐,完全无循环)
Numpy 1.20+ 版本提供了sliding_window_view函数,可以直接生成时间序列的滑动窗口,完美匹配你的需求。步骤如下:
- 先把DataFrame转换成Numpy数组:
import numpy as np import pandas as pd from numpy.lib.stride_tricks import sliding_window_view # 你的示例数据 data = pd.DataFrame(np.reshape(range(25), (5,5)), columns = ["u_0", "u_1", "u_2", "u_3", "u_4"]) arr = data.values l = 2 # 历史时间步数
- 生成滑动窗口并调整顺序:
# 生成包含当前+ l个历史时刻的滑动窗口,每个窗口是连续的l+1行 windows = sliding_window_view(arr, window_size=l+1, axis=0) # 反转窗口内的行顺序,让当前时刻在前,历史时刻依次在后 y = windows[:, ::-1, :]
- 验证结果:
你要的y(3)对应y[1](因为窗口从k=l开始,索引0对应k=2,索引1对应k=3),打印看看:
print(y[1])
输出正好是你要的结果:
[[15 16 17 18 19] [10 11 12 13 14] [ 5 6 7 8 9]]
如果你的Numpy版本低于1.20,可以用stride_tricks.as_strided手动实现滑动窗口(同样无循环):
def custom_sliding_window(arr, window_size): n_rows, n_cols = arr.shape stride_row, stride_col = arr.strides return np.lib.stride_tricks.as_strided( arr, shape=(n_rows - window_size + 1, window_size, n_cols), strides=(stride_row, stride_row, stride_col) ) # 使用自定义函数 windows = custom_sliding_window(arr, l+1) y = windows[:, ::-1, :]
方法二:Pandas 矢量化拼接(几乎无循环)
如果你更习惯用Pandas,可以结合shift和concat来实现,只有最后转形状用了轻量的列表推导(数据量大时也可以用矢量化操作替代):
l = 2 # 生成当前时刻和l个滞后时刻的DataFrame列表 dfs = [data.shift(i) for i in range(l+1)] # 按列拼接成一个大DataFrame,每行包含当前+历史的所有变量 combined = pd.concat(dfs, axis=1).dropna() # 去掉前l行缺失值 # 将每行转成(l+1, n_vars)的形状,得到所有y(k) y_list = [row.values.reshape(l+1, -1) for _, row in combined.iterrows()]
验证y(3):y_list[1]就是对应结果,和Numpy方法一致。
额外提示
如果需要把二维的特征向量展开成一维(比如用于机器学习模型输入),只需对每个y(k)执行flatten()或者reshape(-1)即可,比如:
y_flat = y.reshape(y.shape[0], -1) # 批量转一维
内容的提问来源于stack exchange,提问作者h3h325
相关产品推荐
相关产品推荐

