4. 数据探索与可视化:用Pandas读取SCADA数据,Matplotlib/Seaborn画趋势图与热力图
好,咱们进入实战环节的第四步。前面你拿到了SCADA数据,也做了清洗,现在该看看这些数据到底长什么样了。
我个人习惯,拿到任何数据集,第一件事不是建模,而是画图。你想想看,一堆数字摆在那,你很难看出门道。但一旦变成曲线、变成色块,很多规律就自己跳出来了。这就像医生看心电图,波形比数字直观得多。
4.1 用Pandas读取SCADA数据
SCADA系统记录的数据,通常是CSV格式。每行是一条记录,包含时间戳、风速、功率、温度等字段。我见过有些项目用Excel存,但说实话,数据量一大,Excel就卡死了。CSV才是工业界的通用语言。
读取代码很简单,但有几个坑要注意:
import pandas as pd
# 读取SCADA数据
df = pd.read_csv('scada_data.csv', parse_dates=['timestamp'], index_col='timestamp')
# 看一眼数据长啥样
print(df.head())
print(df.info())
print(df.describe())
parse_dates 这个参数,我建议你养成习惯加上。SCADA的时间戳格式五花八门,有的是"2024-01-15 08:30:00",有的是"2024/01/15 08:30"。Pandas能自动识别大部分格式,但偶尔也会翻车。我曾经遇到过一个项目,时间戳里混了中文"年"字,结果解析失败,排查了半天。
4.2 趋势图:看风机状态随时间怎么变
趋势图是数据探索的起点。说白了,就是把一个变量随时间画成一条线。比如风速、功率、齿轮箱温度,这些关键参数的变化趋势,能直接反映风机是否健康。
我一般用Matplotlib画趋势图,因为它灵活。Seaborn虽然好看,但定制起来不如Matplotlib顺手。
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
# 设置中文字体(防止乱码)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 画风速和功率的趋势图
fig, ax1 = plt.subplots(figsize=(14, 6))
ax1.plot(df.index, df['wind_speed'], color='blue', label='风速 (m/s)', linewidth=0.8)
ax1.set_ylabel('风速 (m/s)', color='blue')
ax1.tick_params(axis='y', labelcolor='blue')
ax2 = ax1.twinx()
ax2.plot(df.index, df['active_power'], color='red', label='有功功率 (kW)', linewidth=0.8)
ax2.set_ylabel('有功功率 (kW)', color='red')
ax2.tick_params(axis='y', labelcolor='red')
# 美化x轴时间格式
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d'))
ax1.xaxis.set_major_locator(mdates.DayLocator(interval=1))
plt.xticks(rotation=45)
plt.title('风速与有功功率趋势图')
fig.tight_layout()
plt.show()
你看,我用双Y轴把风速和功率画在一起。为什么?因为功率随风速变化,正常情况下应该是一条平滑的曲线。如果出现异常波动,比如风速没变但功率突然掉下来,那大概率是风机出问题了。
df['2024-01-01':'2024-01-07'] 切片看一周的数据,异常往往藏在细节里。
4.3 相关性热力图:找出变量之间的“暧昧关系”
趋势图看的是单个变量随时间的变化。但风机故障往往是多个因素共同作用的结果。比如齿轮箱温度升高,可能跟风速、环境温度、润滑油温都有关系。这时候就需要相关性热力图了。
热力图说白了,就是用一个色块矩阵,展示每两个变量之间的相关系数。颜色越深,相关性越强。红色代表正相关,蓝色代表负相关。
import seaborn as sns
import numpy as np
# 选择数值列(排除时间戳等非数值列)
numeric_cols = ['wind_speed', 'active_power', 'generator_temp', 'gearbox_temp',
'ambient_temp', 'rotor_speed', 'blade_pitch']
# 计算相关系数矩阵
corr_matrix = df[numeric_cols].corr()
# 画热力图
plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix, annot=True, fmt='.2f', cmap='coolwarm',
square=True, linewidths=0.5, cbar_kws={'shrink': 0.8})
plt.title('SCADA参数相关性热力图')
plt.tight_layout()
plt.show()
嗯,这里要注意:相关系数只衡量线性关系。非线性关系它看不出来。比如风速和功率,在额定风速以下近似线性,但超过额定风速后功率就饱和了。这时候相关系数会偏低,但不代表它们没关系。
4.4 核心知识体系:数据探索与可视化流程
下面这张图,是我自己总结的数据探索流程。你照着这个顺序走,基本不会漏掉关键信息。
4.5 避坑指南:我踩过的那些坑
做数据可视化这么多年,有些坑我几乎每个项目都会遇到。分享给你,省得你再走一遍弯路。
- 时间戳乱序:SCADA数据有时会因为网络延迟,导致时间戳不是严格递增的。画图前记得
df.sort_index(inplace=True),否则曲线会乱成一团。 - 数据量太大:如果数据有几十万行,直接画图会卡死。我一般先降采样,比如取每小时的平均值,用
df.resample('1H').mean()。 - 颜色盲区:热力图默认的色板,红绿色盲用户可能分不清。我习惯用
cmap='coolwarm'或cmap='viridis',对色盲更友好。 - 相关性不等于因果:这个老生常谈了,但每次都得提醒。热力图上两个变量高度相关,不代表一个导致另一个。可能是第三个隐藏变量在起作用。
4.6 实战小结
这一章我们做了三件事:用Pandas读数据、用Matplotlib画趋势图、用Seaborn画热力图。这三板斧,基本能帮你摸清SCADA数据的底细。
记住,数据探索不是一次性的。建模过程中,你可能还会回头再看图。比如发现模型效果不好,回去画个图,往往能找到原因。我见过太多人一上来就调模型参数,结果数据本身就有问题,调破天也没用。
好了,数据看完了,下一章咱们就该动手做特征工程了。不过那是后话,先把今天的图存好,后面分析故障案例时还会用到。
公众号:蓝海数据掘金营,微信deep3321