3、数据预处理流程:数据清洗、时间戳对齐、数据重采样、数据标准化

各位好,我是老张。在风电行业摸爬滚打了十来年,处理过的数据少说也有几百个风场了。今天咱们聊聊数据预处理——说白了,就是给原始数据“洗个澡、理个发”,让它能真正派上用场。

很多刚入行的朋友,拿到SCADA数据就直接往模型里塞。结果呢?模型跑出来一塌糊涂。我当年也犯过这个错,后来才明白:数据预处理占整个分析工作量的70%以上。你想想看,如果数据本身就有问题,再牛的算法也白搭。

核心观点:预处理不是可有可无的步骤,而是决定分析成败的关键环节。跳过预处理,等于盖楼不打地基。

数据预处理流程 ① 数据清洗 去除异常值 处理缺失值 ② 时间戳对齐 统一时间基准 插值对齐 ③ 数据重采样 降采样/升采样 统一频率 ④ 数据标准化 Z-score / Min-Max 消除量纲影响 四个步骤环环相扣,缺一不可

3.1 数据清洗——先把垃圾扔掉

数据清洗,说白了就是挑出那些明显不对劲的数据。我在西北某风场处理数据时,发现风速显示80m/s——这什么概念?台风也就这水平。后来一查,是传感器被冻住了。

常见的脏数据有这么几类:

  • 超出物理范围的值:比如风速大于50m/s,或者功率为负值。这些明显不合理。
  • 缺失值:SCADA系统偶尔会丢包,导致某些时间点没有数据。
  • 重复值:同一时间戳出现多条记录,可能是通讯故障导致的。
  • 死值:连续几个小时数值完全不变,传感器八成是坏了。

我的经验:清洗时别太激进。有些看似异常的值,可能是真实工况(比如切出风速附近)。我一般会先画个分布图,看看数据整体长什么样,再决定阈值。

处理缺失值,我常用的方法:

# 线性插值——适合短时间缺失
df['风速'].interpolate(method='linear', inplace=True)

# 前向填充——适合传感器短暂离线
df['风速'].fillna(method='ffill', inplace=True)

# 直接删除——缺失太多就别要了
df.dropna(thresh=len(df.columns)*0.7, inplace=True)

3.2 时间戳对齐——让所有数据对上号

这个问题很隐蔽,但坑特别多。不同传感器、不同采集系统,时间戳可能差了好几秒。我记得有一次做功率曲线分析,怎么画都不对,折腾了两天才发现——风速和功率的时间戳差了整整10秒。

为什么会这样?因为风速仪和电表用的是不同的时钟源。一个走GPS,一个走本地时钟,时间一长就漂移了。

对齐的方法:

  1. 统一时区:全部转成UTC,别用北京时间、格林威治混着来。
  2. 确定基准频率:比如统一到10分钟一个点。
  3. 插值对齐:把不同频率的数据插到同一个时间轴上。
# 设置时间索引,统一时区
df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True)
df.set_index('timestamp', inplace=True)

# 重采样到10分钟间隔
df_resampled = df.resample('10T').mean()

注意:对齐时千万别用四舍五入取整。比如10:03:45的数据,直接当成10:00处理,误差会累积。一定要用插值或重采样。

3.3 数据重采样——统一节奏

风场的数据采集频率五花八门。有的传感器1秒一个点,有的10分钟才传一次。你想想看,如果直接拿这些数据做分析,结果能准吗?

重采样就两个方向:

  • 降采样:从高频到低频。比如把1秒的数据聚合成10分钟的平均值。适合做长期趋势分析。
  • 升采样:从低频到高频。比如把10分钟的数据插值到1分钟。适合做实时监控。

我个人习惯用降采样。原因很简单——高频数据噪声大,取均值能平滑掉很多毛刺。但要注意,降采样会丢失细节信息,得根据具体场景来选。

# 降采样:取10分钟平均值
df_10min = df.resample('10T').mean()

# 升采样:线性插值到1分钟
df_1min = df.resample('1T').interpolate(method='linear')

3.4 数据标准化——让不同量纲的数据能一起玩

风速的单位是m/s,功率的单位是kW,温度的单位是℃。这三个数值的量级差太多了。如果你直接拿原始数据做机器学习,风速的权重会被严重低估。

标准化的目的,就是消除量纲影响。常用的方法有两种:

方法 公式 适用场景
Z-score标准化 z = (x - μ) / σ 数据近似正态分布,有异常值
Min-Max归一化 x' = (x - min) / (max - min) 数据有明确边界,如功率在0~额定值之间
from sklearn.preprocessing import StandardScaler, MinMaxScaler

# Z-score标准化
scaler = StandardScaler()
df_scaled = scaler.fit_transform(df[['风速', '功率', '温度']])

# Min-Max归一化
scaler = MinMaxScaler()
df_norm = scaler.fit_transform(df[['风速', '功率', '温度']])

避坑指南:标准化时,一定要先拆分训练集和测试集。用训练集的均值和标准差去标准化测试集,千万别混在一起算。我曾经犯过这个错,导致模型在测试集上表现虚高,上线就崩了。

嗯,数据预处理这块,说白了就是四个字:认真、细致。每一步都不难,但漏掉任何一步,后面的分析都可能翻车。我见过太多人在这上面栽跟头了,希望你能少走些弯路。


专注资料整理