尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
时间序列预测中的数据滑窗操作实例(python实现)
前言时间序列预测里有一个几乎绕不开的前处理步骤滑窗rolling window / sliding window。它的作用是按固定长度在序列上开一个「窗口」每次向后移动若干步把一段历史切成许多个小片段。切出来的片段既是特征过去 N 个观测值也是标签下一个或下几个观测值的来源。围绕这个话题有两个说法需要先纠正。第一很多资料说「用itertools.windowed做滑窗」但标准库itertools里并没有windowed这个函数。目前itertools里和窗口沾边的是两个itertools.pairwisePython 3.10 新增产出相邻的两元组和itertools.batchedPython 3.12 新增把序列切成不重叠的固定长度块3.13 起多了strict关键字参数。真正实现重叠滑窗的sliding_window是官方文档「迭代器配方Recipes」一节里给出的示例函数属于教学与孵化性质需要自己复制到代码里它不是内置函数。这一点版本号必须标对因为pairwise和batched的适用版本完全不同。第二讲「时间序列预测」的文章默认用 pandas 和 numpy。本文的示例全部只用标准库collections、itertools、statistics复制到.py文件里就能跑不需要装任何东西。如果你用的是第三方数据分析库它们一般也提供滚动窗口的现成接口例如常见的rolling一类方法但那属于另一套 API具体参数名与默认行为以该库官方文档为准本文不展开。一、滑窗的基本形态先把术语固定下来。给定一个序列和一个窗口长度 n滑动一步的窗口是seq[i : in]滑动 k 步就整体右移 k。窗口之间的重叠由步长决定步长 1 表示每次只挪一格相邻窗口重叠 n-1 个元素。# 适用于 Python 3.8seq [10, 12, 11, 13, 15, 14, 16]n 3for start in range(0, len(seq) - n 1):print(seq[start:start n])这段会依次打印[10, 12, 11]、[12, 11, 13]、[11, 13, 15]、[13, 15, 14]、[15, 14, 16]共 5 个窗口。窗口数量有一个简单公式对长度为 L、窗口为 n、步长为 s 的序列窗口个数是floor((L - n) / s) 1当 L 大于等于 n 时上例中 L7、n3、s1得到 floor(4/1)1 5与循环次数一致。当 L 小于 n 时窗口不存在个数按 0 处理。用range的上界len(seq) - n 1正好覆盖这个公式如果len(seq) n上界小于等于 0range为空不产出任何窗口。这就是为什么不需要额外判断「序列太短」——边界自然成立。二、四种纯标准库实现2.1 列表切片最直观# 适用于 Python 3.8def windows_slice(seq, n, step1):返回所有窗口组成的列表序列过短时返回空列表。if n 0:raise ValueError(窗口长度 n 必须为正整数)if step 0:raise ValueError(步长 step 必须为正整数)return [seq[i:i n] for i in range(0, len(seq) - n 1, step)]优点是短、可读、一次拿到全部结果。缺点是内存占用与窗口总数成正比长度为 10 万的序列、窗口 100、步长 1会产生约 10 万个列表对象。做大序列处理时这一步往往是内存峰值所在。2.2 生成器一次只产一个窗口# 适用于 Python 3.8def windows_iter(seq, n, step1):惰性产出窗口元组序列过短时一个都不产出。if n 0:raise ValueError(窗口长度 n 必须为正整数)if step 0:raise ValueError(步长 step 必须为正整数)for i in range(0, len(seq) - n 1, step):yield tuple(seq[i:i n])和上一个的差别只有两点用yield而不是return 列表以及产出tuple而不是list元组可哈希、更省内存也防止调用方误改窗口内容。注意生成器只能遍历一次需要多次遍历时要显式list(...)物化。2.3 deque(maxlenn)适合流式数据collections.deque支持maxlen参数一旦长度达到上限再往一端添加元素另一端会自动丢弃一个。这天然就是一个滑窗。# 适用于 Python 3.8from collections import dequedef windows_deque(iterable, n, step1):对流式输入做滑窗只保留最近 n 个元素。if n 0 or step 0:raise ValueError(n 与 step 都必须为正整数)window deque(maxlenn)for index, item in enumerate(iterable):window.append(item)if len(window) n and (index - n 1) % step 0:yield tuple(window)推演一下逻辑第index个元素追加后若 deque 已满它里面装的就是下标index-n1到index这 n 个元素于是窗口的起始下标是index - n 1。当这个起始下标能被step整除时输出就等价于按步长取样。这个版本的真正价值在于它不需要序列事先存在内存里。输入可以是文件逐行读取的迭代器、网络流、传感器回调deque始终只持有 n 个元素。前面两种实现都要求len(seq)可用也就是要求整个序列已在内存。2.4 itertoolspairwise 与 batched# 适用于 Python 3.10import itertoolsprint(list(itertools.pairwise([1, 2, 3, 4]))) # [(1, 2), (2, 3), (3, 4)]pairwise相当于 n2、步长 1 的滑窗写起来最短。# 适用于 Python 3.12import itertoolsprint(list(itertools.batched([1, 2, 3, 4, 5], 2))) # [(1, 2), (3, 4), (5,)]注意batched是不重叠的切块且最后一块可能不满——上例最后一个元组只有一个元素。从 3.13 起它可以接受strictTrue此时长度不足的末块会抛ValueError。把batched当成滑窗用是常见误解它产出的是「分块」不是「滑动窗口」。工具引入版本是否重叠末块是否补齐itertools.pairwise3.10重叠n2不适用itertools.batched3.12不重叠不补齐末块较短sliding_window配方需自己复制无版本门槛重叠不适用deque(maxlenn)2.6 起一路可用重叠不适用2.5 官方配方 sliding_window官方文档的迭代器配方一节给出了这个版本可以直接抄进代码# 适用于 Python 3.8from collections import dequefrom itertools import islicedef sliding_window(iterable, n):把数据收集成重叠的定长块。iterator iter(iterable)window deque(islice(iterator, n - 1), maxlenn)for x in iterator:window.append(x)yield tuple(window)它的巧妙之处是先用islice预填 n-1 个元素此后每消费一个就产出一个满窗。要注意它只支持步长 1需要别的步长得自己加计数器并且当输入长度不足 n 时for循环一次都不会执行产出为空——行为与前面几个实现一致。三、时间序列预测中的实际用法滑窗在预测任务里的核心用途是把一条序列改造成「监督学习」形式的样本对(用过去 n 个值, 预测下一个值)。# 适用于 Python 3.8def make_supervised(series, n):把序列切成 (历史窗口, 下一时刻) 的样本对。samples []for i in range(0, len(series) - n):history tuple(series[i:i n])target series[i n]samples.append((history, target))return samplesseries [10, 12, 11, 13, 15, 14, 16]for history, target in make_supervised(series, 3):print(history, -, target)关键点在于上界这里是len(series) - n比纯滑窗少了 1。因为每个窗口还要配一个「窗口之后的那个值」作为标签最后一个位置没有后继必须丢掉。如果误写成len(series) - n 1最后一对会在取series[i n]时越界。再看一个多步预测的例子用窗口预测接下来的多个值。# 适用于 Python 3.8def make_multistep(series, n, horizon):产出 (历史窗口, 未来 horizon 个值) 的样本对。if horizon 1:raise ValueError(horizon 必须为正整数)samples []for i in range(0, len(series) - n - horizon 1):history tuple(series[i:i n])future tuple(series[i n:i n horizon])samples.append((history, future))return samplesprint(make_multistep(list(range(1, 9)), 3, 2))它的上界是len(series) - n - horizon 1确保窗口和未来段都在序列内。这种「长度参数互相牵制」的地方是滑窗代码最容易算错的地方。还有一个纯标准库就能做的滑窗特征窗口均值。它常常作为简单基线模型。# 适用于 Python 3.8import statisticsdef rolling_mean(series, n):产出每个满窗的均值不足 n 个元素的位置不产出。for window in windows_iter(series, n):yield statistics.mean(window)print([round(v, 2) for v in rolling_mean([10, 12, 11, 13, 15], 3)])statistics.mean(data)接受可迭代对象并返回算术平均。这里用生成器串生成器整条链路上不会一次性物化所有窗口。四、边界与参数的自检清单写滑窗代码之前把这几个问题过一遍能省掉大量调试问题结论序列长度小于窗口长度不产出任何窗口不报错步长为 0 或负数range会抛ValueError应在函数入口显式校验窗口长度为 0 或负数切片语义无意义必须显式拒绝预测任务里是否需要留标签位需要上界要再减 1或多步预测时减 horizon输入是生成器怎么办用deque(maxlenn)版本或先物化成元组是否需要多次遍历窗口生成器只能遍历一次需要时先list()关于「序列短于窗口」不同的库有不同的选择有的直接报错有的返回空。本文所有实现统一采用「返回空」这一种行为因为它和range的自然语义一致调用方用if not windows:判断即可。常见坑点1. 以为标准库有itertools.windowed❌ 写import itertools然后调用itertools.windowed(seq, 3)得到AttributeError。 ✅ 标准库没有这个函数。重叠滑窗要么用deque(maxlenn)自己写要么复制官方配方里的sliding_window不重叠分块用 3.12 起的itertools.batched。2. 把batched当滑窗❌ 用itertools.batched(seq, 3)做时间序列滑窗结果窗口之间不重叠训练样本数少了一大截。 ✅ 明确了需求再选不重叠分块用batched重叠滑窗自己实现。3. 预测任务的上界忘了减 1❌ 用range(0, len(series) - n 1)生成 (窗口, 下一值) 样本最后一项取标签时IndexError。 ✅ 标签需要后继值上界改为len(series) - n。4. 步长传 0❌windows_slice(seq, 3, step0)range抛ValueError: range() arg 3 must not be zero错误信息指向内部实现看不出是调用方的问题。 ✅ 在函数开头显式判断if step 0: raise ValueError(...)把错误信息说清楚。5. 生成器被遍历两次❌ 把windows_iter(...)的返回值存下来先for一遍求最大值再for一遍求均值第二遍什么都不产出。 ✅ 生成器只能遍历一次要多次用就list(...)物化或者每次重新调用生成函数。6. 对生成器输入用切片版本❌ 把open(path)之类的迭代器直接传给windows_slicelen()报TypeError: object of type TextIOWrapper has no len()。 ✅ 流式输入用deque(maxlenn)版本或者先data tuple(...)物化再用切片版本。7. 用列表推导一口气造出全部窗口❌ 在几十万点的序列上用列表版滑窗内存被窗口副本撑满甚至触发内存不足。 ✅ 用生成器版本或deque版本让峰值内存只与窗口长度有关。8. 误以为窗口元素是副本就安全❌ 用切片版滑窗得到的是浅拷贝窗口里装的是元素引用的副本元素本身若可变改一个元素会同时影响所有含它的窗口。 ✅ 需要真正独立的窗口内容时做深拷贝或者保持窗口内元素不可变时间序列通常是数字不涉及这个问题。总结场景推荐实现关键点序列短、要一次性结果列表切片内存与窗口数成正比序列长、只需遍历一遍生成器只能遍历一次流式输入、内存受限deque(maxlenn)不需要len()只留最近 n 个只要相邻两元组itertools.pairwisePython 3.10 起不重叠定长分块itertools.batchedPython 3.12 起末块可能不满通用重叠滑窗官方sliding_window配方需自行复制只支持步长 1滑窗本身不复杂出错几乎都出在参数关系上窗口长度、步长、序列长度三者之间要满足L n而做预测时还要再为标签留出位置。与其每次重新推导不如把上界公式写进注释再用一个极短的序列比如长度为 1跑一遍边界异常会立刻暴露。最后重申两点itertools里没有windowed能用的是 3.10 的pairwise和 3.12 的batched以及本文所有实现都只依赖标准库凡是涉及第三方数据分析库的滚动窗口接口请以对应库的官方文档为准。
RELATED

相关推荐

1994年汇编拆解:TSR安全卸载与中断向量/MCB状态回滚

1994年汇编拆解:TSR安全卸载与中断向量/MCB状态回滚

简介:这是一份聚焦雷军早年汇编作品的欣赏与研读材料,面向对底层编程、DOS时代软件环境及技术人物成长轨迹感兴趣的开发者与计算机史爱好者。压缩包内含1个PDF文件,约116KB,以代码截图与注释文本为主,便于直接阅读RI.A…

📅 2026/10/30 5:09:56
教育专用大模型落地:L0/L1/L2架构、微调与验收

教育专用大模型落地:L0/L1/L2架构、微调与验收

简介:面向教育研究者、K12教师与教育科技从业者的《重构教育图景:教育专用大模型研究报告(简版)》,由中国教育科学研究院数字教育研究所与之江实验室智能教育研究中心联合编写,聚焦教育专用大模型的技术基础…

📅 2026/10/30 5:09:56
从最大似然到梯度下降:线性回归与逻辑回归全链路解析

从最大似然到梯度下降:线性回归与逻辑回归全链路解析

简介:这份线性回归算法小组报告PPT面向机器学习入门学习者、课程小组汇报与算法基础复习场景,围绕连续变量预测问题梳理线性回归的核心脉络。内容以工资、年龄预测贷款额度的小案例切入,讲解拟合平面、误差高斯分布假设、似然函数与对数似然推…

📅 2026/10/30 5:09:56
MORE NEWS

更多资讯

📰

Sonnet 5.5接入与Claude Code配置实战指南

刚看完Anthropic的新版模型发布信息,说实话第一反应不是“哇吊打谁”,而是“那旧工作流里的模型调用逻辑要不要立刻换”。很多人的第一反应都是去看它跑分怎么贴脸Opus,其实我更关心另一件事:这个战力级别的模型,落在我…

📰

大数据技术栈解析:从采集到应用的全流程指南

1. 大数据技术栈全景概览大数据技术栈经过近二十年的发展,已经形成了完整的生态系统。作为Apache软件基金会最重要的技术领域之一,大数据项目占据了其顶级项目的半壁江山。这些项目共同构成了从数据采集、存储、计算到应用的完整技术链条。当前主流的大数…

📰

人类语音产生机制与机器听觉技术解析

1. 人类发音的生理基础人类的发音系统是一个精密的生物机械装置,主要由三大功能模块构成:呼吸系统、发声系统和调音系统。这套系统协同工作产生的声波,经过口腔、鼻腔等共鸣腔的调制,最终形成我们听到的语音。1.1 呼吸系统的动力作…

📰

ESP32-P4嵌入式LLM推理:从0.61到4.31 tok/s的工程突破

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

S变换Matlab实现:从公式到代码的时频分析指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Linux mkdir命令详解:从基础使用到高级技巧

1. Linux mkdir命令基础解析mkdir(make directory)是Linux系统中最基础且使用频率最高的目录管理命令之一。作为文件系统操作的基石命令,任何Linux用户都需要熟练掌握其使用方式。这个命令自Unix时代诞生至今,其核心功能始终保持稳…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬