如何基于同日邻近时刻与前两日相同时刻进行电力时序数据缺失值插补
本文介绍一种针对电力负荷时间序列数据的精细化缺失值插补方法:对每个缺失点,综合考虑当日前后各2个相邻时间点(如01:00缺失时取00:00、00:30、01:30、02:00)、以及前2天同一时刻共5个有效观测值的均值进行填充。
本文介绍一种针对电力负荷时间序列数据的精细化缺失值插补方法:对每个缺失点,综合考虑当日前后各2个相邻时间点(如01:00缺失时取00:00、00:30、01:30、02:00)、以及前2天同一时刻共5个有效观测值的均值进行填充。
在电力负荷分析中,缺失值往往具有强时空相关性——同一电表的日间模式稳定,且相邻时刻及历史同期(如同一时刻前1–2天)的读数高度相似。简单使用全局均值或线性插值会忽略这一特性,导致插补偏差。本文提出一种时空协同插补策略:对任意缺失值 df.loc[i, col](col 为时间列如 '01:00'),构造候选值集合:
- 同日邻近值:取该行所在日期(date)下,col 列前后各2个非空时间点(需确保列名按时间顺序排列);
- 历史同期值:取该行 date - pd.Timedelta('1D') 和 date - pd.Timedelta('2D') 对应行中 col 列的值(若存在且非空);
- 最终插补值:上述最多5个有效数值的算术平均值。
✅ 关键前提:时间列('00:00', '00:30', ..., '23:30')必须按升序排列,且 date 列为 datetime64 类型。
以下为完整实现代码(含健壮性处理):
import pandas as pd
import numpy as np
def impute_electricity_ts(df, time_cols=None):
"""
基于同日邻近时刻 + 前2天同期时刻的均值插补电力时序缺失值
Parameters:
-----------
df : pd.DataFrame
输入DataFrame,含 'meter IDs', 'date' 及多个时间列(如 '00:00')
time_cols : list of str, optional
时间列名列表;若为None,则自动识别除 'meter IDs' 和 'date' 外的所有列
Returns:
--------
pd.DataFrame : 插补后的DataFrame(原地修改并返回)
"""
# 确保date列为datetime类型
df = df.copy()
df['date'] = pd.to_datetime(df['date'])
# 自动识别时间列
if time_cols is None:
time_cols = [c for c in df.columns if c not in ['meter IDs', 'date']]
# 按meter ID和date排序,确保时序连续
df = df.sort_values(['meter IDs', 'date']).reset_index(drop=True)
# 构建日期索引映射:{meter_id: {date: row_idx}}
idx_map = {}
for mid, group in df.groupby('meter IDs'):
idx_map[mid] = {row['date']: idx for idx, row in group.iterrows()}
# 遍历每个时间列
for col in time_cols:
for i in range(len(df)):
if pd.isna(df.at[i, col]):
mid = df.at[i, 'meter IDs']
curr_date = df.at[i, 'date']
candidates = []
# 1. 同日邻近时刻(前后各2个)
# 获取当前行所在日期的所有时间点值(非空)
same_day_rows = df[(df['meter IDs'] == mid) & (df['date'] == curr_date)]
if not same_day_rows.empty:
# 提取所有时间列值(转为Series便于索引)
time_series = same_day_rows.iloc[0][time_cols]
col_pos = time_cols.index(col)
# 前2个:max(0, col_pos-2) 到 col_pos-1
prev_pos = max(0, col_pos - 2)
for j in range(prev_pos, col_pos):
val = time_series.iloc[j]
if pd.notna(val):
candidates.append(val)
# 后2个:col_pos+1 到 min(len-1, col_pos+2)
next_pos = min(len(time_cols), col_pos + 3)
for j in range(col_pos + 1, next_pos):
val = time_series.iloc[j]
if pd.notna(val):
candidates.append(val)
# 2. 前2天同期时刻
for offset in [1, 2]:
ref_date = curr_date - pd.Timedelta(f'{offset}D')
if ref_date in idx_map[mid]:
ref_idx = idx_map[mid][ref_date]
val = df.at[ref_idx, col]
if pd.notna(val):
candidates.append(val)
# 插补:取均值(至少1个候选值才填充,否则保持NaN)
if candidates:
df.at[i, col] = np.mean(candidates)
return df
# 使用示例
# 假设原始df已加载
# result_df = impute_electricity_ts(df)
注意事项与优化建议:
- 性能提示:对大规模数据(>10万行),上述逐行循环可能较慢。可改用 groupby('meter IDs').apply() 并向量化内部逻辑,或借助 numba 加速。
- 边界处理:首日/末日缺失值无法获取前2天数据,函数自动跳过;首/末时间点(如 '00:00' 或 '23:30')缺少前后邻近值,仅使用可用部分。
- 扩展性:可通过参数 window_size=2 和 history_days=[1,2] 封装为通用接口,适配不同粒度(如15分钟)或历史窗口。
- 验证建议:插补后建议绘制某电表连续多日的热力图(seaborn.heatmap),目视检查插补值是否符合日周期规律。
该方法兼顾物理可解释性与统计稳健性,在真实电力场景中显著优于单一维度插补,是负荷数据预处理的推荐实践。
如非特殊说明,本站内容均来自于网友自主分享,如有任何问题均请联系我们进行处理!
猜您喜欢
三角洲行动s10非战斗时刻任务攻略
2026-07-03《三角洲行动》是一款设定在2035年的第一人称特战干员战术射击游戏。三角洲行动的s10赛季终于上线了,还更新了新的3×3任务,那么有不少小伙伴好奇s10非战斗时刻任务怎么做,下面就来告诉大家。 三角洲行动s10非战斗时刻任务攻略 一、任务基础信息一览 任务名称:非战斗时刻 所属类型:赛季标准支线 对局地图:烽火地带(AZ3机密行动专属模式) 完整任务目标 ①汽轮机室东部主路点位,超感回溯作战电台语...
时刻日记app日记发布教程
2026-06-27时刻日记app怎么写日记,打开时刻日记,进入主界面,点击底部“写点什么吧…”的输入框,在输入框中输入日记内容,比如“今天天气晴朗”,输入完成后,点击输入框右侧的发送图标(纸飞机形状)。 时刻日记app日记发布教程: 1、打开时刻日记,进入主界面,点击底部“写点什么吧…”的输入框。 2、在输入框中输入日记内容,比如“今天天气晴朗”,输入完成后,点击输入框右侧的发送图标(纸飞机形状)。 3、发送后,长...
时刻日记app图片插入方法
2026-06-27时刻日记app如何插入图片,打开时刻日记,点击页面底部的输入框就可进入编辑模式,进入编辑界面后,点击+按键就可以导入图片,用户只需选择相册里的图片,即可插入到日记中。 时刻日记app图片插入方法: 1、打开时刻日记,点击页面底部的输入框就可进入编辑模式 2、进入编辑界面后,点击+按键就可以导入图片 3、用户只需选择相册里的图片,即可插入到日记中 以上就是小编整理带来的时刻日记app如何插入图片,图...
硬钢《GTA6》!《幻兽帕鲁》发文:所有项目将同日发售
2026-06-05随着几乎所有游戏都决定挤在9月底发售以避开《GTA6》,《幻兽帕鲁》的发行与传播负责人John'Bucky'Buckley开玩笑说,他要来个“壮烈梭哈”。 此前的索尼StateofPlay发布会有一个共同主题——或许在夏日游戏节和Xbox游戏展示会上也会看到类似现象——那就是大家真的不想和《GTA6》撞档。《鬼武者:剑之道》《控制:共振》和《寂静岭:小镇陷落》都定在9月24日和25日发售,随后一周...
如何修复Python aiohttp请求时出现的ClientPayloadError?
2026-06-04ClientPayloadError表明服务端提前关闭连接,非客户端代码错误;常见于服务端超时、拒绝大响应或代理截断,需通过抓包、检查响应头、服务端日志及添加读取超时和异常处理来定位解决。 ClientPayloadError通常意味着服务端提前关闭了连接 这个错误不是客户端代码写错了,而是aiohttp在读取响应体时发现服务端已经断开了连接。常见于服务端超时、主动拒绝大响应、或代理/网关(如Ng...
如何使用Python监控服务器CPU温度并邮件告警_通过psutil模块读取系统信息
2026-06-04psutil无法直接读取CPU温度,因其依赖系统硬件接口且Linux需lm_sensors支持、Windows/macOS完全不支持;可靠方式是用subprocess调用sensors命令解析输出,并配合邮件告警与健壮性设计。 psutil本身不提供CPU温度读取功能——它无法直接获取温度传感器数据,强行调用psutil.sensors_temperatures()在多数Linux发行版(尤其是无...
如何在Python中验证文件的MD5校验和以确保数据完整性?
2026-06-04必须分块读取,推荐8192或65536字节块大小,以rb模式打开文件,循环调用update(),最后用hexdigest()获取32位小写十六进制字符串;校验时需strip().lower()统一格式并做长度校验。 用hashlib.md5()读取文件并计算校验和 直接调用hashlib.md5()并传入整个文件内容(比如md5.update(f.read()))在大文件上会爆内存。必须分块读取,...
怎样在Python Tkinter中使用线程池处理高并发的GUI数据更新?
2026-06-04不能直接用ThreadPoolExecutor更新Tkinter控件,因为Tkinter的Tcl解释器只允许主线程操作UI;子线程(包括线程池中的工作线程)调用widget方法会引发TclError或卡死;必须通过queue.Queue+root.after()将结果安全传回主线程更新。 为什么不能直接用concurrent.futures.ThreadPoolExecutor更新Tkinter控...
如何在Python 3中正确判断一个对象是否为某个类的实例?
2026-06-04应优先使用isinstance()而非type()做类型判断,因isinstance()遵循MRO、支持继承与ABC,体现鸭子类型哲学;type()仅判别直接类型,适用极少数需严格身份校验的场景。 用isinstance()而不是type() 直接比较type(obj)==SomeClass在绝大多数场景下是错的——它无法识别子类实例。比如isinstance(42,int)返回True,但typ...
为什么Python Django默认使用PBKDF2算法进行密码哈希?
2026-06-04Django默认使用PBKDF2而非Argon2或bcrypt,因其零依赖、NIST合规、迭代与salt可扩展,且默认26万次迭代兼顾安全与性能;make_password和check_password均动态读取PASSWORD_HASHERS[0],支持渐进式算法迁移。 PBKDF2是Django默认密码哈希算法,因为它在安全性、兼容性与可配置性之间取得了最务实的平衡。 为什么不是更“新”的Ar...
