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

如何基于当日前后2值及前2天同期值填充电力时序数据缺失值?

解决Pandas按电表ID和时段填充缺失值的方案

步骤1:数据预处理

先将date列转为datetime类型,再把宽表转换为长表,让每个时段的数据成为独立行,方便后续按电表和时段分组处理。

import pandas as pd
import numpy as np

# 假设原始数据存储在df中
df['date'] = pd.to_datetime(df['date'])

# 宽表转长表:保留电表ID和日期,将时段列转为「时段标识」和「读数」两列
df_long = df.melt(id_vars=['meter IDs', 'date'], var_name='hour_slot', value_name='reading')

# 生成完整时间戳,便于后续定位前后时段与历史同期值
df_long['timestamp'] = df_long['date'] + pd.to_timedelta(df_long['hour_slot'])

步骤2:分组计算填充值

按电表ID和时段分组,对每个缺失值,收集以下有效值取均值填充:

  • 当日该时段前后各2个相邻时段的有效值(比如01:00缺失时,取00:00、00:30、01:30、02:00的有效值)
  • 前1天、前2天同一时段的有效值(比如2020-09-02的01:00缺失时,取2020-09-01、2020-08-31的01:00有效值)
def fill_missing(group):
    # 按时间戳排序,保证时序连续性
    group = group.sort_values('timestamp').reset_index(drop=True)
    
    # 遍历所有缺失值的位置
    for idx, row in group[group['reading'].isna()].iterrows():
        # 收集当日前后2个时段的有效值
        current_day_window = group[
            (group['date'] == row['date']) &
            (group['timestamp'].between(row['timestamp'] - pd.Timedelta(hours=1), row['timestamp'] + pd.Timedelta(hours=1))) &
            (group['timestamp'] != row['timestamp'])
        ]['reading'].dropna()
        
        # 收集前1、2天的同期有效值
        prev_days_vals = []
        for days_back in [1, 2]:
            target_date = row['date'] - pd.Timedelta(days=days_back)
            val = group[
                (group['date'] == target_date) &
                (group['hour_slot'] == row['hour_slot'])
            ]['reading'].dropna()
            if not val.empty:
                prev_days_vals.extend(val.tolist())
        
        # 合并有效值并计算均值填充
        all_valid_vals = np.concatenate([current_day_window.values, prev_days_vals])
        if len(all_valid_vals) > 0:
            group.loc[idx, 'reading'] = np.mean(all_valid_vals)
    return group

# 分组处理缺失值
df_filled_long = df_long.groupby(['meter IDs', 'hour_slot']).apply(fill_missing).reset_index(drop=True)

步骤3:恢复宽表格式

将处理后的长表转回原始的宽表结构:

df_filled = df_filled_long.pivot(index=['meter IDs', 'date'], columns='hour_slot', values='reading').reset_index()

# 可选:恢复原始时段列的顺序,和输入表保持一致
original_time_cols = [col for col in df.columns if col not in ['meter IDs', 'date']]
df_filled = df_filled[['meter IDs', 'date'] + original_time_cols]

补充说明

  • 若某缺失值没有任何有效参考值(如新电表前2天无数据且当日前后时段全缺失),会保留为NaN,可根据需求额外处理这类极端情况。
  • 若需要调整前后时段的数量,可修改pd.Timedelta(hours=1)(当前对应2个30分钟时段)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 16:33:20