数据预处理入门:数据清洗、时间对齐与重采样

说实话,很多刚入行的朋友觉得风电功率预测的核心是算法模型。我一开始也这么想。直到我在项目里被脏数据坑了整整两周,才明白一个道理:数据预处理做不好,后面再牛的模型也是白搭。今天咱们就聊聊数据预处理里最关键的三个环节——数据清洗、时间对齐和重采样。

1. 数据清洗:把垃圾数据挡在门外

数据清洗说白了就是两件事:处理缺失值、处理异常值。我在项目里见过太多因为数据没洗干净导致模型预测偏差大的案例了。

1.1 缺失值处理

风电数据里缺失值很常见。传感器故障、通信中断、存储异常,随便一个原因就能让数据出现空洞。嗯,这里要注意:千万别直接删掉缺失行,除非你确定数据量足够大。

我个人习惯的做法是分情况处理:

  • 连续缺失不超过3个点:用线性插值填充。比如前一个值是5,后一个是7,中间缺的就填6。
  • 连续缺失超过3个点:用前后24小时同一时刻的数据均值填充。因为风电有日周期性,这个做法比较靠谱。
  • 缺失超过50%的变量:直接删除这个变量。我在项目里遇到过风速传感器坏了三个月,这种数据留着也没用。

核心原则:填充缺失值是为了保留数据的时间连续性,而不是为了凑数。填错了比不填更可怕。

# 线性插值示例(Python)
import pandas as pd
import numpy as np

# 假设df是包含风速数据的DataFrame
df['wind_speed'] = df['wind_speed'].interpolate(method='linear')

# 前后24小时同一时刻均值填充
def fill_with_daily_pattern(df, column):
    df[column] = df[column].fillna(
        df.groupby(df.index.hour)[column].transform('mean')
    )
    return df

1.2 异常值处理

异常值比缺失值更隐蔽。你想想看,风速突然飙到100m/s,这明显不合理对吧?但系统不会告诉你这是异常,它只会老老实实记录下来。

我曾经遇到过一个案例:某台风电场连续一周的功率数据都偏高,排查了很久才发现是电流互感器坏了。这就是典型的异常值污染。

我常用的异常值检测方法:

  • 物理阈值法:风速0-40m/s,功率0-额定功率。超出这个范围直接标记为异常。
  • 3σ原则:超出均值±3倍标准差的数据,大概率是异常。这个方法对正态分布的数据效果不错。
  • 四分位距法:超出Q1-1.5IQR或Q3+1.5IQR的数据。这个方法对非正态分布更鲁棒。

注意:异常值不一定要删除。有时候异常值代表的是真实事件(比如切机、限电),这些信息对预测模型很重要。我建议先标记,再根据业务场景决定处理方式。

# 四分位距法检测异常值
def detect_outliers_iqr(data):
    Q1 = data.quantile(0.25)
    Q3 = data.quantile(0.75)
    IQR = Q3 - Q1
    lower_bound = Q1 - 1.5 * IQR
    upper_bound = Q3 + 1.5 * IQR
    return (data < lower_bound) | (data > upper_bound)

2. 时间对齐:让数据站在同一条时间线上

风电数据来源很多:SCADA系统、测风塔、气象预报、电网调度……每个系统的时间戳可能都不一样。有的用整点,有的用半点,有的甚至用随机时间。这就麻烦了。

我记得有个项目,SCADA数据是每10分钟一个点,但气象数据是每15分钟一个点。如果不做时间对齐,模型根本没法用。说白了,时间对齐就是让所有数据都落在同一个时间网格上。

具体做法:

  1. 确定基准时间频率:一般选数据量最大的那个频率作为基准。比如SCADA是10分钟,那就以10分钟为基准。
  2. 创建完整的时间索引:从数据开始到结束,生成连续的基准时间序列。
  3. 重新索引:把所有数据都映射到这个时间序列上。

小技巧:时间对齐时,我习惯用前向填充(forward fill)来处理短时间偏移。比如气象数据晚了2分钟,就用前一个有效值填充。这样能最大程度保留原始信息。

# 时间对齐示例
# 创建10分钟基准时间序列
base_time = pd.date_range(start='2024-01-01', end='2024-01-02', freq='10T')

# 重新索引并前向填充
df_aligned = df.reindex(base_time, method='ffill')

3. 重采样:把数据变成你想要的节奏

重采样和时间对齐有点像,但目的不同。时间对齐是解决不同频率数据的问题,重采样是主动改变数据的频率。

为什么要重采样?举个例子:你手头有1分钟的数据,但预测模型只需要15分钟的数据。直接把1分钟数据扔进模型,计算量太大,而且没必要。这时候就需要降采样。

反过来,如果你只有小时级数据,但模型需要15分钟数据,那就需要升采样。不过说实话,升采样是"无中生有",精度肯定不如原始高频数据。

我常用的重采样方法:

重采样类型 常用方法 适用场景
降采样(高频→低频) 均值、中位数、最大值 减少数据量,匹配模型输入
升采样(低频→高频) 线性插值、样条插值 需要更细粒度的时间序列
聚合采样 求和、计数 计算累计发电量等指标

避坑指南:降采样时,千万别用"最大值"来聚合风速数据。为什么?因为风速的最大值不代表平均风速,用最大值做预测会严重高估发电量。我曾经就犯过这个错,模型预测结果比实际发电量高了30%。

# 重采样示例
# 降采样:从1分钟到15分钟,取均值
df_15min = df.resample('15T').mean()

# 升采样:从小时到15分钟,线性插值
df_15min_up = df.resample('15T').interpolate(method='linear')

知识体系总览

下面这张图把数据预处理的三个核心环节串起来了。你可以把它当作一个检查清单,每次做数据预处理时对照着来。

数据预处理核心流程 原始风电数据 数据清洗 缺失值处理 | 异常值检测与处理 时间对齐 统一时间基准 | 前向填充 | 重索引 重采样 降采样 | 升采样 | 聚合采样

数据预处理这件事,说白了就是"磨刀不误砍柴工"。我见过太多人急着跑模型,结果被数据问题折腾得死去活来。花点时间把数据洗干净、对齐好、重采样到合适的频率,后面建模会顺畅很多。

记住一句话:垃圾进,垃圾出。数据预处理不是可有可无的步骤,它是整个预测流程的基石。希望今天的分享能帮你少走一些弯路。


专注资料整理