3. SCADA数据读取与初步探索

风机SCADA系统通常以固定采样周期(常见为1秒、10秒或1分钟)记录风速、有功功率、转速、桨距角、机舱振动、发电机温度等测点。数据落地形式主要有三类:CSV/文本文件(现场导出、便于人工查看)、数据库表(如MySQL、SQL Server、时序库)、二进制或列式文件(Parquet、HDF5,适合大规模历史数据)。本节以最常见的“多台风机、按天导出的CSV”为对象,完成从读取到初步探索的完整链路。

一、数据文件格式与读取要点

典型SCADA导出文件的列结构为:时间戳列(如 Timestamp 或 Time)、风机标识列(TurbineID)、若干测点列。读取时需重点关注四点:

  • 编码与分隔符:现场文件可能是GBK编码、分号或制表符分隔,直接按默认UTF-8和逗号读取会报错或串列。
  • 时间戳格式:常见 2024-03-01 00:00:00、2024/3/1 0:00,甚至Excel序列号,需显式指定解析格式。
  • 数值列中的脏字符:如 "--"、"N/A"、空字符串、带千分位逗号的数字,应统一转为NaN。
  • 时区与夏令时:若原始时间为本地时间,需确认是否带时区偏移,避免跨天对齐错位。

以Python为例,读取并规范化的核心代码如下(示例参数为合理假设):

import pandas as pd
import numpy as np

df = pd.read_csv(
    "WTG01_20240301.csv",
    sep=",", encoding="gbk",
    na_values=["--", "N/A", "", "null"],
    parse_dates=["Timestamp"],
    date_format="%Y-%m-%d %H:%M:%S"
)
df = df.sort_values("Timestamp").reset_index(drop=True)
df["Timestamp"] = pd.to_datetime(df["Timestamp"], errors="coerce")
df = df.set_index("Timestamp")
print(df.shape, df.index.min(), df.index.max())

读取后先确认三件事:行数是否与理论采样点数一致(如1分钟采样一天应为1440行)、时间范围是否覆盖目标日期、关键测点列是否全部为数值类型。若行数明显偏少,往往意味着文件被截断或存在重复表头。

二、时间戳对齐

多台风机或同一风机不同测点的时间戳常不完全一致:有的从00:00:00开始,有的从00:00:03开始;有的存在重复时间戳;有的在通信中断时整段缺失。对齐的目标是让所有序列落在统一的时间网格上,常用两种方式:

  • 重采样(resample):将原始高频数据聚合到目标频率,如10秒数据聚合为1分钟,取均值或最大值。
  • 重索引(reindex):以标准时间网格为基准,将原始数据映射上去,缺失位置填NaN。
# 统一到1分钟网格,缺失处填NaN
grid = pd.date_range("2024-03-01 00:00:00",
                     "2024-03-01 23:59:00", freq="1min")
df_aligned = df.reindex(grid)

# 若原始为10秒数据,先聚合再对齐
df_1min = df.resample("1min").mean()
df_1min = df_1min.reindex(grid)

对齐后应检查:索引是否严格等间隔、是否存在重复时间戳、缺失比例是否在可接受范围。若某台风机缺失超过30%,通常说明该日通信质量差,需单独标记而非直接参与统计。

三、缺失值与异常值概览

缺失值分为“显式缺失”(NaN、空值)和“隐式缺失”(时间戳跳跃、重复值)。异常值则包括:超出物理量程(如风速为负、功率超过额定值)、长时间恒定不变(传感器卡死)、突变尖峰(通信误码)。初步探索阶段不必急于清洗,而应先量化:

missing_ratio = df_aligned.isna().mean().sort_values(ascending=False)
print(missing_ratio.head(10))

# 简单异常值筛查:超出量程或恒定不变
for col in ["WindSpeed", "ActivePower", "PitchAngle"]:
    s = df_aligned[col]
    print(col, "min/max:", s.min(), s.max(),
          "unique:", s.nunique())

判断依据可参考:风速合理范围约0~40 m/s,有功功率约0~额定功率(如2.0 MW),桨距角约-5°~90°。若某测点唯一值只有1个,说明该时段传感器无变化,应标记为可疑。

四、基本统计描述

对对齐后的数据执行 describe(),可快速获得各测点的计数、均值、标准差、最小值、四分位数和最大值。重点关注:

  • 计数:与总行数对比,判断缺失程度。
  • 均值与中位数差异:差异大说明分布偏斜或存在极端值。
  • 标准差:过小可能卡死,过大可能含尖峰。
  • 最大值/最小值:是否越界,是否出现负功率等异常。

例如,某台风机有功功率统计为:计数1380、均值0.86 MW、标准差0.71 MW、最小值-0.02 MW、最大值2.01 MW。负功率可能来自停机时的厂用电倒送,最大值略超额定值则可能是瞬时过载或量测误差,均需结合运行状态进一步判断。

SCADA数据读取与初步探索链路 ① 文件读取 CSV / 数据库 / Parquet 编码·分隔符·时间格式 脏字符 → NaN ② 时间戳对齐 统一时间网格 resample / reindex 缺失位置填 NaN ③ 缺失/异常概览 缺失比例统计 量程越界·恒定值 尖峰·重复时间戳 ④ 统计描述 count / mean / std min / 25% / 50% 75% / max 关键检查点与判断依据 行数核对 1min采样一天=1440行 偏少→截断/重复表头 时间网格 严格等间隔·无重复 缺失>30%单独标记 量程判断 风速0~40 m/s 功率0~额定·桨距-5~90° 统计异常信号 std过小→卡死 均值≠中位数→偏斜 示例:某台风机1分钟数据统计描述(合理假设) 测点 count mean std min 50% max 判断 WindSpeed 1380 7.42 3.15 0.3 7.1 21.6 正常 ActivePower 1380 0.86 0.71 -0.02 0.78 2.01 需核查

完成上述四步后,应形成一份简短的“数据体检结论”:文件是否完整、时间轴是否连续、各测点缺失比例、是否存在越界或卡死、统计分布是否合理。这份结论将直接决定后续清洗策略与故障诊断的可信度。例如,若风速缺失集中在夜间,可能是通信中断而非传感器故障;若功率长期为负,则需结合停机状态判断是否为厂用电计量。只有先看清数据本身,后续的特征提取与故障判定才有可靠基础。