
简介这份资源是一套完整的电负荷与热负荷预测数据集面向电力系统调度人员、能源管理研究者及机器学习建模者可用于时序分析、需求预测与能源优化研究。压缩包内共41个文件约17.05MB以Python脚本、CSV数据表、TXT气象记录为主另含PDF文献与说明文档。其中CSV文件提供了高精度与热电联产场景下的电负荷、热负荷连续采样数据TXT文件记录了温度、太阳直接辐射、风速等关键气象因子便于分析负荷与气候的关联。配套的Python代码覆盖数据清洗、特征处理与建模流程而Decentralized-Scheduling-Strategy-of-Heating-Systems-master目录中还有分布式供暖系统调度策略的论文与实现代码适合深入探究热负荷优化调度。目前已有1892人学习下载是负荷预测领域兼具数据与代码的实用资源。1. 完整电负荷、热负荷数据负荷预测到底缺的是什么做负荷预测这些年我见过太多人对着一套漂亮的深度学习代码白费劲模型结构新、超参数调得细可预测曲线在真实负荷面前依旧一言难尽。到最后查根因十有八九是数据的问题——时间戳对不齐、节假日没编码、热负荷和气温差了个时区。标题里的“完整电负荷、热负荷数据”说的不是几张Excel表而是一套时间对齐、粒度一致、覆盖多年历史、附带气象与日历上下文、并且清洗干净的时序数据集。对刚入行的电气工程师、供热系统数据分析师、以及正在做多能互补预测的团队来说数据完整度就是预测系统的天花板。这篇笔记把从零构建这套数据的流程、参数和踩坑讲清楚照着搭就能少走弯路。2. 搭建负荷预测数据集从原始计量到可训练样本的标准流程完整数据不等于原始数据堆在一起。我从智能电表和热力站项目里反复整理数据后总结出一条固定流程先确定量测点与时间基准再统一颗粒度再补充外部特征最后切成训练样本。任何一步偷懒后面模型训练都会加倍还回来。2.1 电负荷数据采集量测点、时间戳与粒度的选择电负荷数据的来源一般是智能电表、配电自动化系统或企业能源管理系统。做预测前先确定预测对象是要总关口表的全站用电还是某条馈线的支路负荷两者用途不同数据特征也不同。总关口表相对平滑预测难度低馈线负荷受单一大用户启停影响大毛刺多。所以第一步不是急着写代码而是把目标量测点确认好并保证该量测点在时间段内没有更换表计或改过接线否则数据会存在系统性台阶。时间戳处理是最容易埋雷的位置。电力系统里经常出现设备时区默认UTC、本地读数是北京时间、中间环节又转了一次时区的组合问题。我长期使用的习惯是原始文件在读取时就归一化成带时区的ISO格式存储统一按UTC展示和训练时再转本地时区。下面是一段处理15分钟电负荷数据的常规代码import pandas as pd df pd.read_csv(meter_elec.csv, parse_dates[timestamp]) # 统一转为UTC再转本地时区避免混用 df[timestamp] ( pd.to_datetime(df[timestamp], utcTrue) .dt.tz_convert(Asia/Shanghai) ) df df.set_index(timestamp).sort_index() # 如果有时间戳重复或跳跃先重采样到15分钟网格 df df.resample(15min).mean().interpolate(limit6) df.columns [elec_kw]这段代码做的事情是先让时间戳名副其实再用15分钟网格做重采样。resample(15min)把非整点读数归到最近的整点网格mean()表示一个网格内多条记录取平均适合平衡型表计数据。interpolate(limit6)对单点缺失用线性插值补齐limit6表示连续缺失超过6个点1.5小时时不插值留给后面清洗阶段处理避免把长时间断档硬拉成直线。粒度选择直接影响数据量和模型计算量。做短期预测未来数小时到一天15分钟或1小时粒度最常见做中长期规划日粒度即可。若原始表计只存小时冻结值强行重采样到15分钟并不会增加信息量所以粒度选择应跟表计冻结周期和预测目标匹配而不是越小越好。2.2 热负荷数据采集与电/热数据对齐热负荷数据比电负荷更难弄。热力站的换热机组、楼栋热力入口的计量表通常是供热公司自己装的时间戳精度参差不齐很多表计内部时钟走偏一天能差出几十分钟。在我做过的项目中电表按北京时间走热力表却快了半小时这种情况不少见。因此收到热负荷原始数据后不要急着和电负荷拼接先做一次时钟校验。常用做法是计算两个序列的互相关估算真实延迟。热负荷本身受室外温度影响大又存在管网传输延迟所以它的平滑度比电负荷高很多。处理热负荷数据的代码一般这样写import numpy as np heat pd.read_csv(meter_heat.csv, parse_dates[time]) heat[time] pd.to_datetime(heat[time], utcTrue).dt.tz_convert(Asia/Shanghai) heat heat.set_index(time).sort_index() heat heat.resample(15min).mean().interpolate(limit12) heat.columns [heat_kw] # 重采样到电负荷的时间轴用nearest把热表记录贴近到同一网格 heat_aligned heat.reindex(df.index, methodnearest) df df.join(heat_aligned)这里reindex(..., methodnearest)是把热负荷数据按最近邻方式对齐到电负荷的时间索引。注意只有当热负荷原始时间戳误差小于半个采样间隔时才适合用最近邻如果误差超过7.5分钟最好先做双向重采样再对齐。limit12允许热负荷连续缺失3小时做插值因为供热系统惯性大短时插值比电负荷更安全但超过3小时仍要标记出来。还有一个关键差异北方供热季和非供热季的数据形态完全不同。非供热季热负荷接近零且存在停暖前后数值跳变。我在做数据集时会把供热季标志单独存成一列而不是直接删除非供热季数据后文会说明原因。2.3 天气、日历与节假日特征负荷预测的隐性输入单靠历史负荷序列做预测模型能学到作息规律却学不到气温突变。做过的人都清楚夏天连续高温、冬天寒潮来袭负荷曲线会明显偏离历史模式。所以完整数据集必须包含天气和日历两类外部输入。天气特征最少要包含室外温度和湿度如果数据可得风速、太阳辐射、降雨量也有帮助。温度不能直接当原始值用业界更常换算成供热度日数HDD和制冷度日数CDD核心是设定人体舒适基准温度把温差转换成与负荷大致线性相关的特征。构造方式如下# df中已有温度temp df[HDD] np.maximum(18.0 - df[temp], 0) # 18度以下才供热 df[CDD] np.maximum(df[temp] - 26.0, 0) # 26度以上才制冷 df[weekday] df.index.weekday # 周一0 df[is_weekend] df[weekday].isin([5, 6]) df[is_holiday] df.index.isin(local_holiday_dates)HDD和CDD的基准温度不是固定值南方城市制冷基准可以取24度北方城市供热基准可到20度。参数需要结合当地建筑保温水平和人们的生活习惯来定我一般先用18/26跑一版再根据残差调整。is_holiday必须使用当地真实放假日历注意元旦、春节这类长假不同年份前后调休也不同直接用weekday判断会让模型误把调休工作日当天往周末靠误差一下子就上来了。2.4 构建可训练样本集滑窗、切分与数据保存数据整理好后最后一步把它切成模型能直接吃的样本。最常用的方法是滑动窗口用过去一段已知负荷预测未来一段负荷。这里有两个核心参数input_len和pred_len分别对应输入序列长度和预测序列长度。对电负荷15分钟粒度下输入96个点代表过去24小时预测24个点代表未来6小时对热负荷由于管网惯性大输入窗口通常要更长比如192个点48小时。预测时也可以分多步输出但一次输出比递归多步更省事。切分代码我常用下面这段import numpy as np def make_windows(data, input_len96, pred_len24, stride1): X, Y [], [] for i in range(0, len(data) - input_len - pred_len, stride): X.append(data[i:i input_len]) Y.append(data[i input_len:i input_len pred_len]) return np.array(X), np.array(Y)stride1表示每15分钟生成一个样本样本之间有大量重叠适合样本量小的场景如果数据量大或者训练速度吃紧可以改成stride4相当于每小时取样一个样本。注意这里不能随机打乱后直接划分按时间顺序先取前70%做训练集、中间10%做验证集、最后20%做测试集是负荷预测的默认做法因为预测未来必须用过去的数据。保存时用np.savez或parquet都行关键是同时保存一份meta.json记录输入输出长度、粒度、特征顺序避免一个月后回来看不懂自己存了什么。3. 数据清洗与特征工程让模型学到规律而不是噪声完整数据集是“好数据”还是“脏数据”清洗这关说了算。我见过太多项目把缺失值补零、异常值直接删最后模型跑通了预测值却出现各种反物理现象。这章把清洗和特征工程按步骤展开。3.1 缺失值处理不同缺失场景的三种策略缺失值分三种单个点缺失、连续短段缺失、长时间断档。处理方式完全不同。单个点缺失用前后线性插值就够连续短段缺失比如半小时以内可以用同一时刻前一天的值或前后加权长时间断档超过一天最好在训练时剔除这段区间而不是硬补因为补出来的数据是假的。这里有个容易被忽略的坑如果原始表计直接停机三天补值会把三条完全重复的日曲线插进去模型学不到任何新信息却在验证集上假装表现良好。所以我会在清洗日志里记录每个缺失区间的长度凡超过阈值的数据段一律打上标记供后续训练时掩蔽。代码示例# 缺失超过6个点不做线性插值而是标记为NaN mask df[elec_kw].isna() group mask.astype(int).groupby(mask.ne(mask.shift()).cumsum()).transform(sum) df.loc[mask (group 6), elec_kw] np.nan # 留下有效区间移除无法可靠修复的长断档 valid df[elec_kw].notna() df df[valid]这里的逻辑是先用分组计数找出连续缺失长度超过6个点15分钟粒度下为1.5小时的缺失段不插值直接置回NaN后续用notna()过滤掉。注意这不代表数据不能用了而是要在训练时把断档边界当作样本边界不让窗口跨越这个缺口。3.2 异常值识别如何区分真实负荷尖峰与坏数据负荷数据里的异常值有两类一类是真实的负荷尖峰比如大功率设备突然启动、压铸机同期开机另一类是表计故障或通信跳变造成的坏数据比如突然跳零、数值突然翻几倍。如果一刀切删掉所有尖峰会让模型学不到极端工况但不处理一个坏点就可能毁掉整段训练窗口。我的做法是先做阈值筛查再做人工抽查。阈值筛查用滚动中位数和分位数而不是固定上下限因为负荷具有明显的日内周期性固定阈值很容易误伤。计算如下rolling_med df[elec_kw].rolling(window96, centerTrue).median() rolling_mad (df[elec_kw] - rolling_med).abs().rolling(window96).median() df[is_outlier] (df[elec_kw] - rolling_med).abs() 6 * rolling_mad 1e-3rolling(window96)覆盖一天96个15分钟点MAD中位数绝对偏差比标准差抗扰性强单个坏点不会把阈值拉高。识别出来之后不是删行而是在特征里加一列is_outlier标志让模型知道这个位置的数据可信度低如果坏点刚好在预测标签窗口内则把整个样本排除。用中位数而不是均值能保住真实尖峰。3.3 特征工程滞后项、滚动统计量与温差把原始负荷喂给模型往往不足以让模型捕捉“今天和昨天同时刻的关系”。常见做法是构造滞后项和滚动统计量。滞后项就是当前时刻前24小时、前48小时、前7天同时刻的负荷值滚动统计量是过去1小时、3小时、24小时的平均值和标准差。这些特征对XGBoost、LightGBM这类树模型效果尤其明显对Transformer模型则可以用Embedding替代但仍建议保留。原因很简单模型自己学长期依赖需要很大参数量直接拷贝一份“昨天同时刻”进特征成本低、效果好。构造代码df[lag_24h] df[elec_kw].shift(96) # 前24小时同时刻 df[lag_168h] df[elec_kw].shift(672) # 前7天同时刻 df[ma_1h] df[elec_kw].rolling(4).mean() df[ma_24h] df[elec_kw].rolling(96).mean().shift(1)shift(96)在15分钟粒度下正好是24小时前构造ma_24h时先滚动再shift(1)保证只使用当前时刻之前的24小时不把当前时刻的信息泄漏进特征。同一天同时刻的负荷具有很强的相似性这在负荷预测领域几乎是公开的规律但前提是数据里没有节假日和调休因素的干扰。所以滞后项要跟日期特征配合使用周末样本不要继承工作日的滞后值否则模型会被误导。3.4 归一化与数据泄露防范数据泄露是负荷预测里最容易犯又最难发现的错误之一。最典型的泄露是用全量数据的均值和标准差做归一化再用同样的归一化参数切分验证集和测试集。这样一来验证集的信息已经通过统计量进入了训练过程测试误差天然偏乐观部署后却会打回原形。正确做法是先切分时序数据再只在训练集上fit归一化器验证集和测试集用训练集的参数transform。MinMaxScaler还是StandardScaler选择不大关键是别跨切分边界fit。下面是一段安全处理from sklearn.preprocessing import StandardScaler train_end int(len(df) * 0.7) val_end int(len(df) * 0.8) train, val, test df[:train_end], df[train_end:val_end], df[val_end:] scaler StandardScaler() train_scaled scaler.fit_transform(train) val_scaled scaler.transform(val) test_scaled scaler.transform(test)除了归一化特征构造也会引入泄漏。比如用“当日平均气温”作为预测未来6小时负荷的特征就不合理因为预测时刻还没过完当天平均气温本身是未来信息。我一般用“气象预报值”或“最近3小时平均气温”替代并在特征命名里注明_forecast。既然要做成完整数据集这些细节都要写进说明哪个特征是原始值、哪个是派生值、哪个有缺失风险。很多项目后来说不清数据怎么来的就是因为没做这一点。4. 电负荷与热负荷预测的数据边界时间粒度、预测步长与惯性差异4.1 时间粒度怎么选15分钟、1小时还是1天数据粒度决定了模型能看到的细节也决定了数据量。同样一年数据15分钟粒度有35040个点1小时粒度只有8760个点日粒度只有365个点。面对不同预测场景选择优先级完全不同。我整理了一张选择参考表应用场景推荐粒度数据量1年模型适配配变短期负荷预测、需求响应15分钟35040点LSTM、Transformer调度计划、现货辅助1小时8760点XGBoost、LSTM中长期规划、年度预测1天365点Prophet、线性模型15分钟粒度适合捕捉短时波动和设备启停但对数据质量要求更高单点坏数据影响更大1小时粒度平滑了大多数毛刺模型表现更加平稳日粒度只能刻画宏观趋势对天气突变不敏感。做多能互补项目时电、热、气、冷的粒度最好统一否则下游耦合模型会很难对齐。我一般会把最小公倍数作为统一粒度电热都用15分钟或1小时不要一边15分钟一边1小时。4.2 预测步长短期、中期、长期分别需要什么数据预测步长和输入特征强相关。短期预测0-24小时依赖历史负荷和气象预报数据粒度要细训练数据覆盖至少一年最好包含完整四季。中期预测1-7天对粒度要求下降但需要数值气象预报数据以及更长的历史窗口三年以上数据才能让模型学到天气模式与节假日模式的组合。长期预测月/年主要依赖日粒度的多年数据以及经济、人口这类外生变量负荷序列自身的历史形态反而只是辅助。预测步长的选择也决定要不要引入气象预报特征。短期预测直接用当天预报气温即可中期预测最好用未来7天的数值天气预报并把气温预报不确定性考虑进特征里。比如把最高温和最低温的预报差作为“昼夜温差”特征很多中期模型的误差来自温度预报偏低的累积。这些都在数据组织阶段就得提前决定模型训练时没有后悔药。我在实际项目中会发现一个普遍现象数据时间跨度不够时换模型是解决不了问题的。很多团队只有半年数据却硬要预测下一个供暖季结果模型只能死记硬背上一个冬天的形状。要让预测样本覆盖足够的极端天气最少要保持完整两年历史宁可数据粒度粗一点也不要跨越太短。4.3 区域差异与供热惯性为什么热负荷比电负荷难做电负荷由一个一个设备实时用电叠加而成响应快受电价波动和生产计划影响明显。热负荷则要经过一次换热、管网传输、建筑散热整个系统惯性很大同一时刻的热负荷其实反映的是前几个小时乃至前一天的热需求。所以热负荷自相关性极强前24小时的值对下小时预测比气温更重要但这也是双刃剑一旦进入寒潮初期历史值反而引导模型低估新增供热需求。区域差异也很突出。北方集中供热与南方分散制热的数据特征完全不同前者以集中供热为主系统有很大惯性后者用热泵和电采暖热负荷与电价、气温强相关。我在建模时会专门把“是否为集中供热”“供热季连续天数”作为区域元数据写入配置避免在南方数据上套北方模型。一个完整的电热数据集通常包含多个量测点不同量测点的负荷形态差异很大。工业园的用电高峰和商场正好错开供热换热站有的一次网、二次网都计量需要明确预测对象是二次网的末端热负荷还是热源出入口的总热量。字段命名也要统一常见命名习惯是sitename_metric_unit比如heat_station_A_kw避免把多个站的数据拼在一起时互相混淆。数据边界这件事不是可有可无的东西它直接决定了模型什么时候可以泛化、什么时候应该提醒使用者不要外推。5. 负荷预测数据里的五个坑现象、原因、解决数据工作没有玄学很多“模型不好”最后都查出来是数据问题。下面五条是我自己踩过且反复见到的坑每条按现象、原因、解决三步写。5.1 预测曲线整体滞后一天现象模型预测值和真实值曲线形状几乎一样但整体平移了约24小时训练集效果还凑合测试集上RMSE偏高。原因时区处理不一致。原始电表按UTC记录我却只做了to_datetime没转时区导致和按北京时间标注的日期特征错位8小时。同时滞后特征shift(96)在错误时区下实际对应的是错误时刻模型只能从数据里学到“今天等于昨天同一表读数”的退化关系。解决统一时间戳规范所有原始数据先转UTC存储训练前统一转本地时区。这一步看似基础但能消除一大批“滞后一天”问题。我后来在数据pipeline入口加了一个函数专门处理时区再没犯过同类错误。5.2 周末预测误差暴增现象模型在工作日表现得不错每到周末误差就显著增大节假日尤其严重。原因没有把周末和节假日编码成特征或者编码了但训练集里周末样本占比太小。树模型会默认把所有样本当作工作日处理。解决在特征中加入is_weekend和is_holiday并把滞后项按日期类型分成工作日滞后和周末滞后两套。具体做法是先用工作日数据构造滞后值再用历史周末数据构造一套“上次同时刻周末值”模型在周末样本上强制使用后者误差立刻降下来。5.3 极端高温天预测集体失灵现象连续高温预警期间模型预测值明显低于实际负荷误差是平时的数倍。原因训练集覆盖时间段内没有出现过类似高温天气温度特征分布没有覆盖这个区间。模型在已知区间内学得很好一外推就翻车。解决扩充训练数据时间跨度至少要包含两个完整夏季同时给温度特征加上clip上限或者使用“历史最大温和最高负荷”做残差修正。短期的后悔药是给极端温度区间单独训练一个修正模型长期方案还是得靠数据积累。5.4 电热联合训练结果互相矛盾现象电负荷和热负荷联合建模时整体loss下降但单独看电负荷预测精度反而比单模型更差。原因两套数据来自不同系统时间戳没对齐。电表按整点冻结热力表却是整点过12分钟记录表观上同时刻的数据实际相差12分钟相关性分析又被时间戳错位破坏模型学到的是错位后的假规律。解决对电、热两段序列做互相关分析计算延迟量并补偿后再拼接。具体说把热负荷整体平移若干个15分钟点找到使相关系数最大的偏移量再以该偏移量重排数据。这样才能保证两套数据在同一时间轴上。5.5 一阶差分后出现负负荷现象把负荷序列做一阶差分后曲线出现毫无物理意义的大幅负值而且和原始尖峰位置对应不上。原因前面异常值处理时把识别出的坏点直接置成0差分后一个正常点减0就会出现一个巨大正峰反过来又会出现负值。坏的修正逻辑掩盖了真实负荷形态。解决异常值不要用简单置零而是用插值、中位数替代或直接置NaN更重要的是保留一个is_outlier标签列不把修正过程和原始过程混在一起。模型在训练时可以选择忽略这些位置而不是被迫学习一段由修正逻辑造的假序列。6. 让数据更值钱联合预测与数据质量审计6.1 把电热做成联合预测数据完整的电、热数据完全可以组织成多通道样本用多任务模型同时预测电负荷和热负荷。我会把数据集重组成X为[N, input_len, features]Y为[N, pred_len, 2]的结构其中两个输出通道分别是电负荷和热负荷。热负荷在非供热季全为0需要额外加一个season_mask通道告诉模型什么时候该学习输出零什么时候该学习供热曲线。6.2 滚动回测验证数据是否够完整用滚动回测来检验。做法是从测试期起点开始每次用截止到当天的数据重训模型预测未来24小时然后向后移动一天重复该过程。滚动回测会暴露那些一次性切分看不出的问题比如模型的季节性退化、数据漂移。我一般会用这个结果决定是否值得增加特征或新增数据。6.3 质量审计清单最后是沉淀下来的审计清单检查项通过标准时间戳全部为统一时区无混用采样间隔与声明粒度一致无随机间隔缺失率单段缺失低于阈值总体缺失不超过历史10%异常值已标记未删除关键尖峰特征泄漏归一化参数只由训练集拟合对齐电热数据相关性偏移已补偿基准对比上时刻值或同昨日值误差要明显低于模型误差这套清单看着朴素但没有它们“完整数据”就只是一句空话。数据质量不是一次性能做完的我的习惯是每个季度重跑一遍审计把新数据追加进训练集时重新检查对齐和缺失然后再重新滚动回测。希望帮到你。本文还有配套的精品资源点击获取