简介这份资源面向电力系统、能源管理与负荷预测方向的研究人员、学生及工程技术人员提供了一套完整的电负荷与热负荷时间序列数据可用于训练和验证负荷预测模型、分析气候因素对用能需求的影响并支撑分布式供暖系统调度策略的仿真研究。压缩包共41个文件约17.05MB以19个Python脚本、10个CSV数据表、8个TXT文本为主另含2份PDF论文与演示文档、1份许可证和1份说明文档涵盖电热负荷序列、标准负荷曲线、温度、太阳直接辐射与风速等气象变量以及分布式供暖调度策略的完整代码与论文材料。目前已有1892人学习下载。读者可借助这些数据开展时间序列分析、机器学习建模、气候敏感性分析并结合调度算法代码复现实验、优化能源利用效率为科研选题或工程实践提供可直接上手的数据与代码基础。1. 电热负荷数据到底长什么样从一份园区实测数据说起去年冬天帮一个工业园区做综合能源改造对方甩过来一个压缩包说“这是我们的电负荷和热负荷数据你看着用”。打开一看两个 Excel一个叫“电表读数”一个叫“换热站记录”时间戳对不齐采样间隔一个 15 分钟一个 1 小时热负荷那列还混着“停供”两个汉字。这就是绝大多数人拿到“完整电负荷、热负荷数据”时的真实处境——数据是有的但离“能喂给负荷预测模型”还差着十万八千里。这篇笔记要讲的就是这件事当你手里有一份电负荷、热负荷数据怎么把它从原始记录变成能训练预测模型的干净数据集中间每一步该怎么做、参数怎么设、哪里最容易翻车。适合做综合能源、园区微网、建筑能耗方向需要同时预测电和热两种负荷的工程师。核心难点不在模型在数据本身——电和热的时间尺度、物理惯性、缺失模式完全不同用同一套清洗逻辑硬套模型精度一定上不去。2. 电热负荷数据的物理差异决定了清洗策略2.1 为什么电负荷和热负荷不能用同一套预处理电负荷的本质是功率单位 kW采样频率高波动剧烈分钟级就能从 200kW 跳到 800kW。热负荷的本质是热量单位 kW 或 GJ/h受建筑热惯性影响变化平缓但存在“供回水温差”这个中间变量——很多时候你拿到的不是热负荷本身而是流量乘以温差算出来的一旦流量计或温度传感器漂移热负荷数据会出现系统性偏差。我一般会先做一件事把两类数据的统计特征拉出来对比。电负荷看峰谷差、爬坡率、日内方差热负荷看与室外温度的相关系数、滞后时间。如果热负荷和室外温度的相关系数低于 0.5大概率是计量有问题不是天气不冷。import pandas as pd import numpy as np # 假设已读入两个 DataFrameelec_df电、heat_df热 # 统一时间索引为 DatetimeIndex elec_df[timestamp] pd.to_datetime(elec_df[timestamp]) heat_df[timestamp] pd.to_datetime(heat_df[timestamp]) elec_df.set_index(timestamp, inplaceTrue) heat_df.set_index(timestamp, inplaceTrue) # 电负荷15分钟粒度看日内峰谷差 elec_daily elec_df[power_kw].resample(D).agg([min, max, mean, std]) elec_daily[peak_valley_ratio] elec_daily[max] / elec_daily[min].replace(0, np.nan) # 热负荷1小时粒度看与室外温度的相关性 # 假设有 temp_df 室外温度 merged heat_df[heat_kw].resample(H).mean().to_frame().join( temp_df[outdoor_temp].resample(H).mean(), howinner ) corr merged[heat_kw].corr(merged[outdoor_temp]) print(f热负荷与室外温度相关系数: {corr:.3f})这段代码的逻辑是先分别看两类数据的“性格”。电负荷的峰谷比如果超过 5说明有大型冲击性设备后续要做异常值检测热负荷相关系数低于 0.5先别急着建模去查换热站的一次侧流量和二次侧供回水温差。参数上resample(D)和resample(H)的粒度选择取决于你的预测目标——如果做日前预测电用 15 分钟、热用 1 小时是常见做法。2.2 时间对齐电热联合预测的第一个硬骨头电和热的采样时间戳很少天然对齐。电表可能是整点过 3 分、18 分、33 分、48 分换热站可能是整点过 7 分。直接merge会产生大量 NaN。常见做法是重采样到统一频率但这里有个坑电负荷用均值重采样会削峰热负荷用插值会引入虚假惯性。我的习惯是电负荷重采样用mean但额外保留一个max列作为峰值特征热负荷重采样用time插值因为热惯性本身就让曲线平滑线性插值误差可接受。对齐后的时间索引必须是严格等间隔否则后面做滑动窗口会出问题。# 电15分钟均值 15分钟最大值 elec_15 elec_df[power_kw].resample(15T).agg([mean, max]) elec_15.columns [power_mean, power_max] # 热1小时线性插值后重采样到15分钟 heat_15 heat_df[heat_kw].resample(15T).interpolate(methodtime) # 合并 combined elec_15.join(heat_15, howouter) combined combined.interpolate(methodtime, limit4) # 最多补1小时 combined.dropna(inplaceTrue)limit4的意思是连续缺失超过 4 个点即 1 小时就不补了直接标记为缺失段。这个参数很关键——热负荷停供超过 1 小时插值出来的数据是假的不如让模型学会处理缺失。2.3 缺失模式的识别随机缺失还是系统性缺失电热负荷数据的缺失从来不是随机的。电表掉线往往是通信故障表现为连续多个点全缺热负荷缺失往往是停供检修表现为整段为 0 或 NaN。这两种缺失的处理方式完全不同通信故障可以插值停供必须加掩码。我一般会画一张缺失热力图按小时和星期几聚合看缺失是否集中在特定时段。如果电负荷缺失集中在凌晨 2 点到 4 点大概率是电表定时重启如果热负荷缺失集中在工作日白天可能是换热站按需供热。# 生成缺失掩码 combined[elec_missing] combined[power_mean].isna().astype(int) combined[heat_missing] combined[heat_kw].isna().astype(int) # 按小时聚合看缺失分布 missing_by_hour combined.groupby(combined.index.hour)[[elec_missing, heat_missing]].mean() print(missing_by_hour)如果elec_missing在某个小时超过 0.3说明这个时段数据不可靠建模时应该把该时段样本降权或剔除。这个步骤很多人跳过结果模型在凌晨时段误差特别大还找不到原因。3. 从原始表到特征矩阵电热负荷预测的数据工程流水线3.1 异常值检测3σ 还是 IQR电和热要分开选电负荷的异常值检测用 IQR 更稳因为电负荷本身不是正态分布3σ 会把大量尖峰误判为异常。热负荷可以用 3σ因为热惯性让数据接近正态。但这里有个血泪经验换热站刚启动时热负荷会有一个陡升这个陡升是真实工况不是异常用任何统计方法都会把它标出来。我的做法是分两步先做统计检测再用物理规则过滤。物理规则包括热负荷不能为负除非是供冷工况、电负荷不能超过变压器容量、热负荷变化率不能超过某个阈值比如 10 分钟变化超过额定值的 30%。def detect_outliers_iqr(series, k1.5): q1, q3 series.quantile([0.25, 0.75]) iqr q3 - q1 lower, upper q1 - k * iqr, q3 k * iqr return (series lower) | (series upper) def detect_outliers_physical(series, max_rate, max_val): rate series.diff().abs() return (rate max_rate) | (series max_val) | (series 0) # 电IQR 物理上限 elec_outlier detect_outliers_iqr(combined[power_mean], k2.0) | \ detect_outliers_physical(combined[power_mean], max_rate500, max_val2000) # 热3σ 物理规则 heat_outlier detect_outliers_physical(combined[heat_kw], max_rate200, max_val1500)k2.0比默认的 1.5 更宽松因为电负荷尖峰多太严会把真实峰值删掉。max_rate和max_val必须根据你的实际装机容量填不能抄。3.2 特征构造电热耦合特征才是提分关键只用电负荷历史预测电负荷用热负荷历史预测热负荷精度天花板很低。电热联合预测的真正价值在于构造耦合特征电负荷与热负荷的比值、热负荷的滞后电负荷、室外温度与热负荷的交互项。我一般会构造这几类特征时序特征前一小时、前 24 小时同时刻、前 168 小时同时刻的电和热耦合特征电热比、电热滚动相关系数24 小时窗口气象特征室外温度、湿度、风速以及它们的滞后值日历特征小时、星期、是否节假日# 时序滞后特征 for lag in [1, 4, 24, 96, 168]: combined[felec_lag_{lag}] combined[power_mean].shift(lag) combined[fheat_lag_{lag}] combined[heat_kw].shift(lag) # 电热比 combined[elec_heat_ratio] combined[power_mean] / combined[heat_kw].replace(0, np.nan) # 24小时滚动相关系数 combined[elec_heat_corr_24h] combined[power_mean].rolling(96).corr(combined[heat_kw]) # 室外温度交互 combined[heat_temp_interact] combined[heat_kw] * combined[outdoor_temp]shift(168)是前一周同时刻这个特征对捕捉周周期非常有效。rolling(96)是 24 小时窗口15 分钟粒度相关系数能反映电热耦合强度的变化——比如周末电热比升高因为办公区电负荷降了但供热没停。3.3 数据集划分时间序列不能随机切这是新手最容易翻车的地方。用train_test_split随机切时间序列会导致未来信息泄露验证集精度虚高上线后直接崩。正确做法是按时间顺序切前 70% 训练中间 15% 验证后 15% 测试。如果做多步预测还要保证测试集的预测窗口不重叠。n len(combined) train_end int(n * 0.7) val_end int(n * 0.85) train combined.iloc[:train_end] val combined.iloc[train_end:val_end] test combined.iloc[val_end:] # 标准化只用训练集的均值和方差 from sklearn.preprocessing import StandardScaler scaler StandardScaler() scaler.fit(train[[power_mean, heat_kw, outdoor_temp]]) train_scaled scaler.transform(train[[power_mean, heat_kw, outdoor_temp]]) val_scaled scaler.transform(val[[power_mean, heat_kw, outdoor_temp]]) test_scaled scaler.transform(test[[power_mean, heat_kw, outdoor_temp]])标准化必须用训练集的统计量不能全量 fit。这个细节很多人知道但经常忘尤其是用 Pipeline 的时候。4. 避坑与排查电热负荷数据清洗的 5 个真实翻车现场4.1 现象热负荷插值后曲线过于平滑模型学不到动态原因用了interpolate(methodlinear)对长时间缺失段插值把停供时段补成了虚假的平稳曲线。解决对连续缺失超过 4 个点的段不插值改为标记缺失掩码让模型自己学。4.2 现象电负荷预测在凌晨误差突然变大原因凌晨电负荷基数小IQR 检测把正常的小幅波动标成了异常清洗后数据被“削平”。解决电负荷异常检测分时段做凌晨用更宽松的 k 值比如 3.0白天用 1.5。4.3 现象电热比特征出现无穷大原因热负荷为 0 时做了除法。解决replace(0, np.nan)后再做除法或者加一个极小值1e-6。但更好的做法是热负荷为 0 时电热比直接置 NaN让模型处理缺失。4.4 现象验证集 loss 很低测试集 loss 高出一大截原因特征构造时用了全局滚动统计比如全量数据的滚动均值导致验证集看到了未来信息。解决所有滚动特征必须在训练集上计算统计量再应用到验证和测试集或者用expanding代替rolling并配合shift。4.5 现象热负荷与室外温度相关系数只有 0.2原因拿到的热负荷是瞬时流量不是热量或者供回水温差传感器装反了。解决先确认热负荷的计算公式如果是流量×温差检查温差是否为供减回流量单位是 m³/h 还是 L/s。这个坑我踩过两次每次都是现场仪表问题不是数据问题。5. 进阶技巧用滞后互相关确定电热耦合的最佳时间窗电和热之间的耦合不是瞬时的。电负荷升高可能因为启动了电锅炉热负荷会在 15 到 30 分钟后才响应反过来热负荷升高可能因为循环泵启动电负荷会立刻响应。这个时间差就是滞后互相关要解决的问题。我一般会算电热之间的互相关函数找到相关性最高的滞后阶数然后用这个阶数构造特征。具体做法对电和热序列分别做标准化计算不同滞后下的 Pearson 相关系数画出来看峰值位置。from scipy.signal import correlate elec_norm (combined[power_mean] - combined[power_mean].mean()) / combined[power_mean].std() heat_norm (combined[heat_kw] - combined[heat_kw].mean()) / combined[heat_kw].std() # 互相关取前 96 个滞后24小时 cc correlate(elec_norm.fillna(0), heat_norm.fillna(0), modefull) lags np.arange(-len(elec_norm)1, len(elec_norm)) mid len(cc) // 2 window 96 cc_window cc[mid-window:midwindow] lags_window lags[mid-window:midwindow] best_lag lags_window[np.argmax(cc_window)] print(f电热互相关峰值滞后: {best_lag} 个15分钟点即 {best_lag*15} 分钟)如果best_lag是正数说明电负荷领先热负荷负数则相反。我做过的一个园区项目里这个值是 2即电领先热 30 分钟因为电锅炉启动后热量传到二次侧需要时间。把这个滞后阶数用在特征构造里热负荷预测的 MAPE 从 12% 降到了 8.7%。还有一个验证技巧把电热耦合特征单独拿出来训练一个简单模型看特征重要性。如果elec_heat_corr_24h的重要性排在前三说明耦合特征有效如果排在后半段可能是你的数据里电热本身就不耦合这时候强行做联合预测反而会拖累精度。最后说个习惯每次清洗完数据我会把原始序列、清洗后序列、缺失掩码画在一张图上肉眼过一遍。统计指标再漂亮也不如看一眼曲线——有一次就是看图发现热负荷在春节那几天被插值成了正常值实际上园区放假停供了这个错误统计检测完全没报出来。数据清洗没有后悔药只有多看多查。希望帮到你。本文还有配套的精品资源点击获取