第4章:数据清洗与预处理
数据清洗这事儿,我做了快十年风电项目,每次都得花掉整个数据流水线40%的时间。你想想看,风机上的传感器可不是实验室里的精密仪器,风吹日晒、雷打雨淋,数据能干净才怪。今天咱们就聊聊,怎么把这堆「脏数据」收拾利索。
4.1 缺失值处理
先说缺失值。我遇到过最夸张的一次,某台风机连续3小时的振动数据全是NaN。查了半天,原来是传感器接头被鸟啄松了。嗯,这行就是这样,什么奇葩事都有。
缺失值处理,我个人习惯分三步走:
- 先诊断:搞清楚缺失是随机的,还是系统性的
- 再决策:缺失比例低于5%,直接删除;超过30%,必须插补
- 后执行:选对插补方法
常用的插补方法,我整理了一张表:
| 方法 | 适用场景 | 我踩过的坑 |
|---|---|---|
| 前向填充 | 缓慢变化的温度、压力 | 风速突变时千万别用,会滞后 |
| 线性插值 | 短时间缺失(<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分钟一次。三个数据源时间戳对不上,怎么分析?
我的做法是:
- 统一时间基准:全部转成UTC时间,避免时区问题
- 确定目标频率:根据分析需求选。做功率曲线用10分钟平均,做振动分析用1秒
- 重采样策略:降采样用均值,升采样用插值
举个例子,把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 知识体系总览
下面这张图,是我自己总结的数据清洗流程。每次做新项目,我都会先过一遍这个框架:
核心要点:数据清洗不是一次性工作。在实时数据流里,每个窗口都要重复这套流程。我习惯把它封装成一个pipeline,每5分钟自动跑一次,出问题就报警。
好了,这一章的内容就这些。数据清洗看着琐碎,但做不好后面全是坑。我见过太多项目,算法模型调得再好,数据一塌糊涂,结果全是白费功夫。记住一句话:垃圾进,垃圾出。
公众号:蓝海数据掘金营,微信deep3321