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能自动识别大部分格式,但偶尔也会翻车。我曾经遇到过一个项目,时间戳里混了中文"年"字,结果解析失败,排查了半天。

⚠️ 注意: 如果时间戳列名不是'timestamp',记得改成你实际列名。另外,index_col设为时间戳,后续做时序分析会方便很多。

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()

嗯,这里要注意:相关系数只衡量线性关系。非线性关系它看不出来。比如风速和功率,在额定风速以下近似线性,但超过额定风速后功率就饱和了。这时候相关系数会偏低,但不代表它们没关系。

🔍 实战经验: 我做过一个项目,热力图上显示齿轮箱温度和发电机温度相关系数高达0.92。当时我以为是传感器串扰,后来排查发现是冷却系统共用了同一个散热器。这个发现直接帮客户省了一笔更换传感器的费用。

4.4 核心知识体系:数据探索与可视化流程

下面这张图,是我自己总结的数据探索流程。你照着这个顺序走,基本不会漏掉关键信息。

数据探索与可视化核心流程 1. 数据读取 Pandas read_csv 2. 数据概览 head/info/describe 3. 趋势图 Matplotlib折线图 4. 热力图 Seaborn 每个步骤的产出与意义 📊 数据读取 → 确保时间戳正确解析,索引设置合理 📈 数据概览 → 发现缺失值、异常值、数据分布特征 📉 趋势图 → 观察变量随时间变化,发现异常波动点 🔗 热力图 → 找出变量间线性相关性,辅助特征选择 注:非线性关系需结合散点图或领域知识判断

4.5 避坑指南:我踩过的那些坑

做数据可视化这么多年,有些坑我几乎每个项目都会遇到。分享给你,省得你再走一遍弯路。

  • 时间戳乱序:SCADA数据有时会因为网络延迟,导致时间戳不是严格递增的。画图前记得 df.sort_index(inplace=True),否则曲线会乱成一团。
  • 数据量太大:如果数据有几十万行,直接画图会卡死。我一般先降采样,比如取每小时的平均值,用 df.resample('1H').mean()
  • 颜色盲区:热力图默认的色板,红绿色盲用户可能分不清。我习惯用 cmap='coolwarm'cmap='viridis',对色盲更友好。
  • 相关性不等于因果:这个老生常谈了,但每次都得提醒。热力图上两个变量高度相关,不代表一个导致另一个。可能是第三个隐藏变量在起作用。
💡 我的习惯: 画完热力图后,我会挑出相关系数绝对值大于0.7的变量对,单独画散点图确认一下。有时候能看到明显的非线性关系,这时候相关系数就骗人了。

4.6 实战小结

这一章我们做了三件事:用Pandas读数据、用Matplotlib画趋势图、用Seaborn画热力图。这三板斧,基本能帮你摸清SCADA数据的底细。

记住,数据探索不是一次性的。建模过程中,你可能还会回头再看图。比如发现模型效果不好,回去画个图,往往能找到原因。我见过太多人一上来就调模型参数,结果数据本身就有问题,调破天也没用。

好了,数据看完了,下一章咱们就该动手做特征工程了。不过那是后话,先把今天的图存好,后面分析故障案例时还会用到。


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