第二讲:数据采集与预处理——打好分析地基
各位同行,今天咱们聊聊发电量分析里最基础、也最容易被忽视的一环——数据采集与预处理。我常说一句话:垃圾进,垃圾出。你模型再漂亮,算法再高级,数据源头要是出了问题,结果就是白忙活。
我自己就吃过这个亏。刚入行那会儿,拿到一套SCADA数据直接开干,结果分析出来的结论跟现场实际情况差了十万八千里。后来一查,原来是某个采集终端坏了三个月,数据全是重复值。从那以后,我养成了一个习惯:拿到数据,先花30%的时间做清洗和预处理。别嫌慢,这步省不了。
2.1 数据源类型——三种主流数据源
电力系统的数据源,说白了就三大类。我一个个说。
SCADA(监控与数据采集系统)
这是咱们最熟悉的。SCADA系统覆盖全厂,采集频率一般在1秒到1分钟之间。它主要采集什么?有功功率、无功功率、电压、电流、开关状态这些。精度嘛,一般0.5级到0.2级,够用。
PMU(相量测量单元)
PMU是个好东西。它采集频率高,一般30~60帧/秒,能捕捉到暂态过程。精度也高,相角误差不超过0.1度。但PMU数据量大,一天就能产生几个GB的数据。我建议:做暂态分析用PMU,做稳态分析用SCADA,别混着用。
电表数据
电表数据是结算依据,精度最高,一般0.2S级或0.5S级。但采集频率低,通常15分钟或1小时一个点。电表数据有个特点——不可篡改,所以做电量平衡分析时,我习惯用电表数据做基准。
| 数据源 | 采集频率 | 精度等级 | 主要用途 | 数据量级 |
|---|---|---|---|---|
| SCADA | 1秒~1分钟 | 0.5级~0.2级 | 稳态监控、趋势分析 | 中等 |
| PMU | 30~60帧/秒 | 相角误差<0.1° | 暂态分析、动态监测 | 极大 |
| 电表 | 15分钟~1小时 | 0.2S级~0.5S级 | 电量结算、平衡分析 | 小 |
2.2 数据采集频率与精度——选对了事半功倍
这里有个常见的误区:频率越高越好?不一定。你想想看,做年度发电量分析,你用PMU的60帧/秒数据,那不是杀鸡用牛刀吗?数据量大不说,处理起来还慢。
我个人习惯这样选:
- 短期分析(秒级~分钟级):用SCADA,1秒或5秒一个点就够了
- 中期分析(小时级~天级):用SCADA或电表,15分钟一个点
- 长期分析(月级~年级):用电表,1小时一个点
- 暂态分析(毫秒级):必须用PMU,别犹豫
2.3 数据清洗——脏数据是分析的头号杀手
数据清洗,说白了就是给数据“洗澡”。我见过太多人,数据拿到手直接建模,结果模型跑出来一塌糊涂。为什么?数据太脏了。
缺失值处理
缺失值怎么来的?通信中断、采集终端故障、人为误操作……原因多了去了。处理方式有几种:
- 删除法:缺失比例小于5%时,直接删掉。简单粗暴,但有效。
- 填充法:用均值、中位数、前向值或后向值填充。我习惯用前向填充,因为电力数据有连续性。
- 插值法:线性插值、样条插值。适合缺失值不多但需要平滑的场景。
# Python示例:缺失值处理
import pandas as pd
import numpy as np
# 读取数据
df = pd.read_csv('power_data.csv', index_col='timestamp', parse_dates=True)
# 检查缺失值
print(df.isnull().sum())
# 前向填充(我常用的方式)
df.fillna(method='ffill', inplace=True)
# 或者线性插值
df.interpolate(method='linear', inplace=True)
异常值处理
异常值比缺失值更麻烦。为什么?因为缺失值你能看到,异常值可能隐藏得很深。我常用的方法:
- 3σ原则:超过均值±3倍标准差的值,视为异常。适合正态分布的数据。
- 箱线图法:超过Q1-1.5IQR或Q3+1.5IQR的值,视为异常。适合非正态分布。
- 业务规则法:比如功率不可能为负值,电压不可能超过额定值的1.2倍。这些规则最可靠。
# Python示例:异常值检测
from scipy import stats
# Z-score方法
z_scores = np.abs(stats.zscore(df['active_power']))
df_clean = df[(z_scores < 3)]
# IQR方法
Q1 = df['active_power'].quantile(0.25)
Q3 = df['active_power'].quantile(0.75)
IQR = Q3 - Q1
df_clean = df[(df['active_power'] >= Q1 - 1.5*IQR) &
(df['active_power'] <= Q3 + 1.5*IQR)]
2.4 数据归一化与标准化——让不同量纲的数据“对话”
归一化和标准化,说白了就是把不同尺度的数据拉到同一个量级。你想想看,电压是kV级别,功率是MW级别,温度是℃级别,直接放一起分析,结果肯定被大数值的变量主导。
Min-Max归一化
把数据映射到[0,1]区间。公式很简单:(x - min) / (max - min)。适合数据有明确上下限的场景,比如电压、频率。
Z-score标准化
把数据转换成均值为0、标准差为1的分布。公式:(x - mean) / std。适合数据分布接近正态的场景,比如负荷、发电量。
鲁棒标准化
用中位数和IQR代替均值和标准差。公式:(x - median) / IQR。适合数据有较多异常值的场景。
# Python示例:归一化与标准化
from sklearn.preprocessing import MinMaxScaler, StandardScaler, RobustScaler
# Min-Max归一化
scaler_minmax = MinMaxScaler()
df_minmax = scaler_minmax.fit_transform(df[['active_power', 'voltage']])
# Z-score标准化
scaler_std = StandardScaler()
df_std = scaler_std.fit_transform(df[['active_power', 'voltage']])
# 鲁棒标准化
scaler_robust = RobustScaler()
df_robust = scaler_robust.fit_transform(df[['active_power', 'voltage']])
嗯,到这里,数据采集与预处理的核心内容就讲完了。记住一句话:数据预处理不是万能的,但不做预处理是万万不能的。下一章咱们聊聊探索性数据分析(EDA),看看怎么从数据里“挖”出有价值的信息。