第2章 气象数据获取与处理

做风电功率预测,说白了就是跟数据打交道。而气象数据,就是咱们这行的「原材料」。原材料不行,后面模型再花哨也白搭。我刚开始做风电项目时,就吃过这个亏——拿到的数据看着挺全,一跑模型全乱套。后来才发现,数据源本身就有问题。

这一章,咱们就聊聊气象数据从哪来、怎么洗、怎么补、怎么归一化。嗯,都是实战中绕不开的坑。

2.1 气象数据源介绍

风电预测常用的气象数据源,主要有三类:NWP、SCADA、测风塔。这三兄弟各有各的脾气,咱们一个一个说。

2.1.1 NWP(数值天气预报)

NWP,全称是Numerical Weather Prediction。说白了,就是用超级计算机跑物理模型,算出未来几天的风速、风向、温度、气压这些。我习惯叫它「大模型预报」。

NWP的特点是:

  • 覆盖范围广——整个区域甚至全球都有
  • 时效性好——能预报未来3-7天
  • 空间分辨率粗——一般几公里到几十公里一个格点
  • 误差随时间增大——越往后越不准

我在项目中遇到过最头疼的事:NWP预报的风速和实际测风塔数据,有时候能差出3-4米/秒。为什么会这样?因为NWP的格点可能离风电场几十公里远,地形一变,风速就变了。

我的习惯:拿到NWP数据后,先跟测风塔数据做对比,算一下偏差。如果偏差太大,就得做「订正」——说白了就是本地化校准。

2.1.2 SCADA数据

SCADA是风电场自己的监控系统。每台风机上都有传感器,实时记录风速、功率、桨距角、转速这些。这个数据的特点是:

  • 时间分辨率高——通常10秒到1分钟一个点
  • 位置准确——就在风机轮毂高度
  • 但噪声大——传感器故障、通信中断、数据跳变,家常便饭

我记得有一次,某台风机SCADA记录的风速连续三天都是12.5米/秒,纹丝不动。一看就知道传感器卡死了。这种数据如果不处理,模型会学出「风速恒等于12.5」这种荒唐规律。

注意:SCADA数据虽然准,但只能反映「过去」和「现在」。做预测时,它更多用来做模型验证和实时校正,不能直接当预报用。

2.1.3 测风塔数据

测风塔是风电场里专门立起来测风的塔,上面装了好几层风速仪、风向标。它比SCADA更专业,数据质量也更高。但问题是:

  • 成本高——建一座塔几十万
  • 数量少——一个风电场可能就1-2座
  • 维护麻烦——结冰、雷击、鸟粪,都能让数据出问题

测风塔数据,我一般把它当作「金标准」。做模型训练时,优先用测风塔数据做标签。如果测风塔坏了,才退而求其次用SCADA。

2.2 数据清洗与异常值处理

数据拿到手,第一件事不是建模,是「洗数据」。我见过太多人上来就调模型,结果跑出来一堆垃圾。你想想看,数据里全是异常值,模型能学出什么好东西?

常见的异常值有这几类:

异常类型 表现 原因
缺失值 NaN、空值 传感器故障、通信中断
跳变值 瞬间从5m/s跳到50m/s 传感器受干扰、雷击
死值 连续多日数值不变 传感器卡死、冻结
越限值 风速超过60m/s(不合理) 量程超限、记录错误

我处理异常值的流程是这样的:

  1. 可视化检查——先画个时序图,一眼就能看出异常
  2. 阈值过滤——风速超过60m/s的直接剔除
  3. 变化率检查——相邻两个点风速变化超过20m/s的,标记为异常
  4. 死值检测——连续24小时数值不变的,全部标记

避坑指南:我曾经犯过一个错——把异常值直接删掉,结果时间序列变得不连续,模型训练时出了大问题。后来我改成「先标记、后插补」,效果好了很多。

2.3 缺失值插补方法

数据清洗完,你会发现有些时间点还是空的。这时候就需要插补。插补方法很多,我常用的就两种:线性插值和KNN插值。

2.3.1 线性插值

线性插值,说白了就是用前后两个点的值,拉一条直线,算出中间缺失点的值。这个方法简单、快,适合短时间缺失(比如1-2个点)。

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

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

# 如果缺失值在开头或结尾,interpolate会保留NaN
# 这时候可以用bfill或ffill填充
df['wind_speed_interp'].fillna(method='bfill', inplace=True)
df['wind_speed_interp'].fillna(method='ffill', inplace=True)

线性插值的局限也很明显:如果缺失时间太长(比如连续几个小时),线性插出来的值会失真。你想想看,风速变化那么剧烈,一条直线怎么可能拟合得好?

2.3.2 KNN插值

KNN插值,全称是K-Nearest Neighbors。它的思路是:找到跟缺失点「最像」的K个邻居,用它们的平均值来填补。这里的「像」,指的是其他特征(比如温度、气压、风向)的相似度。

我为什么喜欢KNN?因为它能利用多维信息。举个例子:某天风速缺失了,但同一天的温度、气压、风向都有记录。KNN会找到历史上跟这些条件最相似的几天,用那几天的风速平均值来填补。

# KNN插值示例(Python)
from sklearn.impute import KNNImputer
import numpy as np

# 假设X是特征矩阵,包含风速、温度、气压、风向等
# 注意:风速列中可能有NaN
imputer = KNNImputer(n_neighbors=5, weights='distance')
X_imputed = imputer.fit_transform(X)

# 提取插补后的风速列
df['wind_speed_knn'] = X_imputed[:, 0]
我的建议:短时间缺失(1-2个点)用线性插值,长时间缺失(超过1小时)用KNN。如果缺失比例超过20%,就别插补了——直接放弃那段数据,或者重新采集。

2.4 数据标准化与归一化

数据洗完了,插补完了,接下来就是标准化。为什么要做这一步?因为不同特征的量纲不一样——风速是0-30m/s,温度是-20到40℃,气压是900-1050hPa。如果不做标准化,模型会「偏袒」数值大的特征。

常用的方法有两种:

方法 公式 适用场景
Min-Max归一化 x' = (x - min) / (max - min) 数据有明确上下界,比如风速0-30
Z-score标准化 x' = (x - μ) / σ 数据分布近似正态,或者有异常值

我个人习惯:如果数据里异常值已经处理干净了,用Min-Max归一化。如果数据里还有少量离群点,用Z-score更稳健。

# Min-Max归一化
from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler(feature_range=(0, 1))
df_scaled = scaler.fit_transform(df[['wind_speed', 'temperature', 'pressure']])

# Z-score标准化
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
df_standardized = scaler.fit_transform(df[['wind_speed', 'temperature', 'pressure']])
注意:标准化时,一定要先拆分训练集和测试集,用训练集的参数去标准化测试集。千万别把测试集的数据混进来算均值和方差——那是数据泄露,模型会「作弊」。

2.5 本章知识体系

说了这么多,咱们用一张图来总结一下本章的核心逻辑。从数据源到最终可用的标准化数据,每一步都有坑,每一步都得小心。

气象数据获取与处理流程 NWP数据 SCADA数据 测风塔数据 数据清洗与异常值处理 可视化检查 → 阈值过滤 → 变化率检查 → 死值检测 缺失值插补 线性插值(短时缺失) → KNN插值(长时缺失) 数据标准化与归一化 Min-Max归一化(有界数据) → Z-score标准化(含离群点) 最终输出:标准化后的可用数据

嗯,这一章的内容就到这。气象数据获取与处理,看似基础,但做扎实了,后面建模会省很多事。我见过太多人在这上面翻车——数据没洗干净,模型跑出来全是错的,还以为是算法不行。其实,数据才是根本。


公众号:蓝海数据掘金营,微信deep3321