第4章:数据清洗与预处理

数据清洗这事儿,我做了快十年风电项目,每次都得花掉整个数据流水线40%的时间。你想想看,风机上的传感器可不是实验室里的精密仪器,风吹日晒、雷打雨淋,数据能干净才怪。今天咱们就聊聊,怎么把这堆「脏数据」收拾利索。

4.1 缺失值处理

先说缺失值。我遇到过最夸张的一次,某台风机连续3小时的振动数据全是NaN。查了半天,原来是传感器接头被鸟啄松了。嗯,这行就是这样,什么奇葩事都有。

缺失值处理,我个人习惯分三步走:

  1. 先诊断:搞清楚缺失是随机的,还是系统性的
  2. 再决策:缺失比例低于5%,直接删除;超过30%,必须插补
  3. 后执行:选对插补方法

常用的插补方法,我整理了一张表:

方法适用场景我踩过的坑
前向填充缓慢变化的温度、压力风速突变时千万别用,会滞后
线性插值短时间缺失(<5个点)长缺失会「拉直」真实波动
中位数填充异常值较多的序列会抹掉峰值,影响故障诊断
KNN插补多变量相关场景计算量大,实时流里慎用

避坑指南:我曾经在风速缺失时用了均值填充,结果后续的功率曲线分析完全失真。后来才明白——风速是强非线性数据,均值填充会直接破坏风能公式的物理关系。

4.2 异常值检测

异常值检测,说白了就是找「不正常的点」。但什么是「不正常」?这得看场景。

我常用的方法有三种:

  • 3σ法则:简单粗暴,适合正态分布的数据。但风电数据往往偏态,慎用。
  • IQR方法:用四分位距,对偏态数据更友好。我个人偏爱这个。
  • 孤立森林:高维数据的好手,但实时流里跑起来有点慢。

给你看段代码,这是我项目里实际用过的:

def detect_anomalies_iqr(series, factor=1.5):
    Q1 = series.quantile(0.25)
    Q3 = series.quantile(0.75)
    IQR = Q3 - Q1
    lower = Q1 - factor * IQR
    upper = Q3 + factor * IQR
    return series[(series < lower) | (series > upper)]

小技巧:风电功率曲线的异常检测,我建议用「风速-功率」二维IQR。单看风速或单看功率,很多异常根本发现不了。比如风速10m/s时功率只有500kW,这明显是限功率运行了。

4.3 数据对齐与重采样

数据对齐,这问题我刚开始做时吃了不少苦头。风机的SCADA系统采样间隔是1秒,振动监测是0.1秒,气象站的数据却是10分钟一次。三个数据源时间戳对不上,怎么分析?

我的做法是:

  1. 统一时间基准:全部转成UTC时间,避免时区问题
  2. 确定目标频率:根据分析需求选。做功率曲线用10分钟平均,做振动分析用1秒
  3. 重采样策略:降采样用均值,升采样用插值

举个例子,把1秒数据重采样到10分钟:

df_resampled = df.resample('10T').agg({
    'wind_speed': 'mean',
    'power': 'mean',
    'status': 'last'
})

注意:重采样时千万别对所有列都用均值。状态码用均值?那出来的数字毫无意义。我习惯对离散变量用「last」或「mode」。

4.4 数据质量评估指标

数据洗没洗干净,得有指标说话。我项目里必看的几个指标:

指标计算公式合格线
完整率有效数据量 / 理论数据量>95%
异常率异常点数 / 总点数<3%
时间一致性相邻时间戳差值标准差<采样间隔的10%
范围合理性是否在物理范围内风速0-50m/s,功率0-额定

为什么会特别关注时间一致性?我记得有一次,某台风机的时间戳突然跳了2小时,排查发现是GPS授时模块坏了。如果不检查这个指标,后续的时序分析全白做。

4.5 知识体系总览

下面这张图,是我自己总结的数据清洗流程。每次做新项目,我都会先过一遍这个框架:

数据清洗与预处理流程框架 原始数据流 缺失值处理(删除/插补) 异常值检测(3σ/IQR/孤立森林) 数据对齐与重采样 数据质量评估(完整率/异常率等) 输入:多源异构数据 关键:判断缺失机制 关键:结合物理约束 关键:统一时间基准 输出:高质量可用数据

核心要点:数据清洗不是一次性工作。在实时数据流里,每个窗口都要重复这套流程。我习惯把它封装成一个pipeline,每5分钟自动跑一次,出问题就报警。

好了,这一章的内容就这些。数据清洗看着琐碎,但做不好后面全是坑。我见过太多项目,算法模型调得再好,数据一塌糊涂,结果全是白费功夫。记住一句话:垃圾进,垃圾出。


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