3、数据预处理:缺失值处理、异常值检测与修正、数据重采样与对齐
各位好,我是老张。今天咱们聊聊数据预处理。说实话,这步看着不起眼,但我在项目里吃过不少亏。你想想看,原始数据就像刚从工地拉来的毛坯房,不经过处理直接往里搬家具,迟早得出事。
我个人习惯把预处理分成三块:缺失值、异常值、重采样对齐。咱们一个一个来。
3.1 缺失值处理
先说缺失值。功率预测的数据里,缺失值太常见了。比如某个测风塔突然断网,或者传感器被冻住了,数据就断了。我遇到过最夸张的一次,连续48小时的数据全是NaN,当时差点把键盘摔了。
处理缺失值,常用的方法就几种:
- 直接删除:如果缺失比例很小(比如<5%),直接删掉那几行,省事。
- 均值/中位数填充:用前后几天的平均值补上。适合波动不大的数据。
- 插值法:线性插值、样条插值。我个人偏爱线性插值,简单且稳定。
- 前向/后向填充:用上一个有效值填充。适合短时间缺失。
核心原则:不要为了填充而填充。如果缺失超过30%,建议直接标记为不可用,别硬补。
举个例子,我常用的代码是这样的:
import pandas as pd
import numpy as np
# 读取数据
df = pd.read_csv('wind_power.csv', index_col='time', parse_dates=True)
# 检查缺失值
print(df.isnull().sum())
# 线性插值
df['power'] = df['power'].interpolate(method='linear')
# 如果缺失太多,直接标记
if df['power'].isnull().sum() / len(df) > 0.3:
print('警告:缺失率过高,建议重新采集数据')
我的小技巧:对于风电功率数据,我习惯先用前后24小时的数据做插值,而不是全局均值。因为功率有日周期性,全局均值会抹掉特征。
3.2 异常值检测与修正
异常值比缺失值更隐蔽。你想想看,一个数值明明存在,但它就是错的。比如风速突然飙到100m/s,或者功率超过额定容量两倍。这种数据如果不处理,模型会被带偏。
我常用的检测方法:
- 3σ原则:超出均值±3倍标准差的值,视为异常。适合正态分布的数据。
- 箱线图法:用四分位距(IQR)判断。超出Q1-1.5IQR或Q3+1.5IQR的,就是异常。
- 领域知识法:比如风速不可能超过50m/s,功率不可能为负。这种硬阈值最可靠。
注意:我曾经犯过一个错——把所有异常值都删了。结果发现有些异常其实是极端天气事件,比如台风过境。这些数据恰恰是模型需要学习的。所以,先判断异常的原因,再决定怎么处理。
修正方法也简单:
- 如果是传感器故障导致的,用插值替换。
- 如果是真实极端事件,保留并标记。
- 如果是明显录入错误,直接删除。
# 3σ法检测异常
mean = df['power'].mean()
std = df['power'].std()
df['is_outlier'] = (np.abs(df['power'] - mean) > 3 * std)
# 修正:用中位数替换
median = df['power'].median()
df.loc[df['is_outlier'], 'power'] = median
避坑指南:我曾经用3σ法处理风电数据,结果发现功率在低出力时段经常被误判为异常。后来改用分时段检测——白天和夜间的阈值分开设,效果好多了。
3.3 数据重采样与对齐
最后一步,重采样和对齐。为什么需要这个?因为数据来源不同,采样频率也不一样。比如气象数据是15分钟一个点,功率数据是5分钟一个点。不统一的话,模型没法用。
重采样的核心是:
- 降采样:从高频到低频。比如5分钟数据变成15分钟。常用聚合函数:均值、最大值、最小值。
- 升采样:从低频到高频。比如15分钟数据变成5分钟。常用插值法。
- 对齐:确保所有时间序列的时间戳一致。比如都从2024-01-01 00:00开始,间隔15分钟。
我个人习惯的做法是:
# 重采样到15分钟
df_resampled = df.resample('15T').mean()
# 对齐多个数据源
weather = weather.resample('15T').interpolate()
power = power.resample('15T').mean()
# 合并
merged = pd.concat([weather, power], axis=1)
merged = merged.dropna() # 对齐后删除不一致的行
关键点:重采样时,一定要考虑业务含义。比如功率数据用均值,风速数据用均值,但风向数据用角度均值?不对,风向是环形数据,得用特殊处理。我在这上面栽过跟头。
下面这张图,是我总结的数据预处理整体流程:
嗯,到这里数据预处理就讲完了。说白了,这步就是给模型喂干净饭。你喂它馊掉的饭,它吐出来的预测结果肯定也是馊的。我见过太多项目,模型调得再好,数据预处理没做好,最后全白费。
记住一句话:垃圾进,垃圾出。预处理花的时间,后面模型训练会加倍还给你。