You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在sklearn时间序列预测中创建滞后特征且不额外占用内存?

用内存共享视图解决滞后项内存爆炸问题

核心思路是利用numpy的内存视图机制,不复制原始数据,通过重新定义数组的步长(stride)来生成滞后项,这样所有滞后特征都共享原始数据的内存,不会额外占用大量空间。下面是一个兼容sklearn的自定义转换器实现:

自定义滞后特征转换器

import numpy as np
from sklearn.base import BaseEstimator, TransformerMixin

class LagFeatureView(BaseEstimator, TransformerMixin):
    def __init__(self, lag_size=180):
        self.lag_size = lag_size

    def fit(self, X, y=None):
        # 无需拟合逻辑,直接返回自身
        return self

    def transform(self, X):
        # 确保输入是连续的numpy数组,避免步长异常
        X = np.ascontiguousarray(X)
        n_samples, n_features = X.shape
        out_samples = n_samples - self.lag_size
        
        if out_samples <= 0:
            raise ValueError(f"样本数({n_samples})小于滞后长度({self.lag_size}),无法生成有效滞后项")
        
        # 使用stride_tricks创建内存共享的滞后视图
        # 形状变为:(有效样本数, 滞后步数, 特征数)
        lagged_array = np.lib.stride_tricks.as_strided(
            X,
            shape=(out_samples, self.lag_size, n_features),
            strides=(X.strides[0], X.strides[0], X.strides[1])
        )
        
        # 将特征维度与滞后维度合并,输出形状为(有效样本数, 特征数*滞后步数)
        return lagged_array.transpose(0, 2, 1).reshape(out_samples, -1)

原理说明

  • np.lib.stride_tricks.as_strided 不会复制原始数据,只是重新定义了数组的读取规则:通过调整步长,让新数组的不同位置指向原始数据的不同切片(比如第i个样本的第k个滞后项,指向原始数据的第i+k个样本的对应特征)。
  • 后续的transpose和reshape操作也不会触发深拷贝,最终返回的数组完全共享原始数据的内存,内存占用和原始数据几乎一致。

使用注意事项

  1. 原始数据不可随意修改:因为滞后视图直接引用原始数据,修改原始数据会同步改变视图中的值,建议在生成视图前完成所有数据预处理。
  2. 输入需为连续数组:如果输入的numpy数组是不连续的(比如经过多次切片、转置),先通过np.ascontiguousarray转为连续数组,避免步长计算错误。
  3. 兼容sklearn流水线:这个转换器继承了BaseEstimator和TransformerMixin,可以直接加入sklearn的Pipeline中,和其他组件无缝配合。

内容的提问来源于stack exchange,提问作者cjm2671

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 16:52:50