4. 机舱数据预处理与特征工程
机舱智能运维的输入并不是“干净的数据表”,而是由采集网关、PLC、振动采集卡、温度变送器等多源设备持续产生的原始测点流。这些数据在进入诊断模型之前,通常要经过缺失值处理、异常值剔除、时序对齐、滑动窗口统计与频域特征提取五个环节。本节以一台主机缸套冷却水系统与一台海水泵的监测数据为例,说明每个环节的具体做法与判断依据。示例中的参数与数值均为教学假设,用于演示计算过程,不代表实测结果。
一、先明确数据对象与时间基准
假设采集系统提供以下测点:缸套冷却水进口温度 TC_IN(采样周期 1 s)、出口温度 TC_OUT(1 s)、海水泵电机三相电流 I_A/I_B/I_C(1 s)、泵体振动加速度 VIB(采样率 10 kHz,按 1 s 分块上传)、泵出口压力 P_OUT(2 s)。不同测点的采样率、时间戳来源和量纲都不同,因此第一步不是清洗,而是统一时间基准:以 1 s 为公共网格,所有高频数据先按秒聚合,低频数据按时间戳对齐到网格。
时间戳约定需在全文保持一致:本文所有时间均为设备本地时间,滑动窗口采用“左闭右开”区间,即窗口 [t-60s, t) 表示包含起点、不含终点,窗口末端时刻 t 的特征只使用 t 之前的数据,避免未来信息泄漏。
二、缺失值处理:先判类型,再选策略
缺失通常分三类:短时丢包(几秒到几十秒)、传感器离线(连续大段为空)、以及“值存在但无效”(如量程外的哨兵值 -999)。处理前应先统计每个测点的缺失率与连续缺失长度。对短时丢包,采用时间插值最合理:温度、压力等缓变量用线性插值;对电流这类波动量,线性插值会削弱峰值,宜用前向填充并标记。对连续缺失超过阈值(例如超过 5 分钟)的区段,不应插值,而应整段标记为无效并在后续特征中置空,防止模型学到伪造的平稳段。
import pandas as pd, numpy as np
# df 已按 1s 网格重采样,索引为时间
df["TC_IN"] = df["TC_IN"].interpolate(method="time", limit=30) # 短缺口线性插值
df["I_A"] = df["I_A"].ffill(limit=10) # 电流短缺口前向填充
gap = df["P_OUT"].isna()
run_id = (gap != gap.shift()).cumsum()
gap_len = df.groupby(run_id)["P_OUT"].transform("size")
df.loc[gap & (gap_len > 300), "P_OUT"] = np.nan # 长缺口保持为空
df["P_OUT_valid"] = (~df["P_OUT"].isna()).astype(int) # 保留有效性标记
关键点是保留“有效性标记”列,而不是把缺失全部填平。后续建模时,标记本身往往是有用特征——传感器离线常与设备异常或维护操作相关。
三、异常值剔除:物理量程 + 统计规则双约束
异常值剔除不能只靠 3σ。机舱数据中,工况切换(如泵启停)会产生真实的阶跃,若一律按统计离群剔除,会误删有效瞬态。建议采用两级约束:第一级是物理量程与变化率约束,例如缸套水温合理范围 20~95 ℃、单秒变化不超过 2 ℃;第二级才是统计规则,用滑动中位数与 MAD(中位数绝对偏差)识别局部离群点,稳健性优于均值方差。
def mad_filter(s, win=61, k=6):
med = s.rolling(win, center=True, min_periods=15).median()
mad = (s - med).abs().rolling(win, center=True, min_periods=15).median()
return (s - med).abs() <= k * 1.4826 * mad
mask = mad_filter(df["TC_OUT"]) & df["TC_OUT"].between(20, 95)
df.loc[~mask, "TC_OUT"] = np.nan # 先置空,再回到缺失值流程处理
注意处理顺序:先把异常值置为缺失,再统一走插值或标记流程,避免“剔除后直接删除整行”造成时间轴断裂。对振动信号,异常值往往表现为短时冲击,应结合后续频域特征判断是故障冲击还是电磁干扰,不宜在时域直接抹掉。
四、时序对齐:重采样、滞后补偿与合并
多源数据对齐包含两层:时间对齐与因果对齐。时间对齐用重采样完成,聚合规则按物理意义选择——温度取均值,电流取均方根,压力取均值,振动按秒计算 RMS 与峰值。因果对齐则要考虑传输与响应滞后:泵出口压力的变化通常滞后于电流变化数百毫秒到数秒,若直接按同一时刻拼接,会削弱电流与压力之间的关联。工程上可先用互相关估计滞后量,再对压力序列做平移补偿。
vib_1s = vib.groupby(vib.index.floor("1s")).agg(
vib_rms=lambda x: np.sqrt(np.mean(x**2)),
vib_peak=lambda x: np.max(np.abs(x)))
base = df.resample("1s").agg({"TC_IN":"mean","TC_OUT":"mean",
"I_A":"mean","P_OUT":"mean"}).join(vib_1s)
# 估计 I_A 与 P_OUT 的滞后(示例:以互相关峰值确定平移量)
lag = np.argmax(np.correlate(base["I_A"].fillna(0),
base["P_OUT"].fillna(0), "full")) - (len(base)-1)
base["P_OUT_aligned"] = base["P_OUT"].shift(int(lag))
对齐完成后应做一致性检查:检查各列时间索引是否完全一致、有效标记是否随平移同步移动、平移后是否引入新的首尾缺失。这一步的产物是一张“宽表”,每行对应一个秒级时刻,列为各测点值及其有效性标记。
五、滑动窗口统计特征:把秒级序列变成窗口样本
诊断模型通常以“一段时间的行为”为输入,因此需要把秒级宽表切分为滑动窗口。窗口长度由物理过程的时间尺度决定:温度类缓变量可用 60 s 窗口、步长 10 s;电流与振动可用 10 s 窗口、步长 1 s。每个窗口计算均值、标准差、最大值、最小值、峰峰值、均方根、斜率等统计量。窗口内有效样本比例低于阈值(如 70%)时,该窗口特征应标记为不可靠。
W, S = 60, 10
feat = base.rolling(W, min_periods=int(W*0.7)).agg(
["mean","std","max","min"]).iloc[::S]
feat[("TC_OUT","range")] = feat[("TC_OUT","max")] - feat[("TC_OUT","min")]
feat[("I_A","rms")] = np.sqrt((base["I_A"]**2)
.rolling(W, min_periods=int(W*0.7)).mean().iloc[::S])
以示例数据说明:若某 60 s 窗口内 TC_OUT 均值为 42.3 ℃、标准差 0.4 ℃、峰峰值 1.6 ℃,而前一窗口标准差为 0.2 ℃,则说明温度波动增大,可能是流量不稳或负荷变化,这类“变化率类特征”比单点值更能反映趋势。
六、频域特征提取:从振动与电流中取故障线索
频域特征主要针对振动和电流。对每个 1 s 振动块做去均值、加汉宁窗、FFT,得到幅值谱,再提取总能量、主频、频谱重心、以及围绕转频与叶片通过频率的边带能量。泵类设备常用指标包括 1×转频、2×转频、叶频及其边带。电流侧可对 I_A 做包络或 Park 矢量变换后取频谱,观察转差频率附近的边带,用于辅助判断转子类问题。
from numpy.fft import rfft, rfftfreq
win = np.hanning(len(block)); fs = 10000
spec = np.abs(rfft((block - block.mean()) * win)) / (len(block)/2)
freqs = rfftfreq(len(block), 1/fs)
f_rot = 24.5 # 示例:泵转频 Hz
band = lambda f0, w=2: spec[(freqs>f0-w) & (freqs<f0+w)].sum()
feats = {"spec_energy": (spec**2).sum(),
"f_peak": freqs[np.argmax(spec)],
"e_1x": band(f_rot), "e_2x": band(2*f_rot),
"centroid": (freqs*spec).sum()/spec.sum()}
频域特征必须与转速关联才有意义。若转速随工况变化,应按转速归一化频率轴,或按转频倍数划分频带,否则同一故障在不同转速下会落在不同频点,导致特征漂移。
七、结果如何判断与交付
完成上述流程后,应形成一份可复查的特征数据集:每行一个窗口,包含窗口起止时间、各测点统计特征、频域特征、有效样本比例与质量标记。判断处理是否合格,可看三点:一是缺失与异常处理前后,关键测点的分布是否发生不合理偏移;二是对齐后电流与压力的互相关是否明显提升;三是窗口特征在已知正常工况下是否稳定、在已知异常段是否出现可解释的变化。若某特征在正常段方差过大,应回查窗口长度、采样率或异常剔除阈值,而不是直接送入模型。
把上述五步串起来,得到的不是“更干净的数据”,而是“带质量标记、时间一致、可解释的窗口特征集”。这一步做扎实,后续的故障分类、趋势预测与远程告警才有可靠输入;反之,若缺失被随意填平、异常被误删、滞后未补偿,模型很可能学到的是采集链路的缺陷,而不是设备的真实状态。