4. 数据清洗与预处理实战

船舶泵组的监测数据在进入预测性维护模型之前,往往“脏”得超出初学者的想象:传感器掉线导致整段缺失、网关重传造成重复时间戳、振动信号叠加了电机基频与管路共振噪声、不同采样频率的传感器各记各的时间。本节以一台船用离心泵组(额定转速1480 r/min,采样周期1 min)的示例数据为对象,完整走一遍用 pandas 与 numpy 完成清洗的实战过程。以下数据均为教学构造的示例,用于说明方法与判断依据。

一、先看清数据:加载与体检

假设原始文件 pump_raw.csv 包含时间戳、泵出口压力(MPa)、轴承温度(℃)、振动速度有效值(mm/s)、电机电流(A)五列。第一步不是急着删改,而是体检:

import pandas as pd
import numpy as np

df = pd.read_csv("pump_raw.csv", parse_dates=["timestamp"])
df = df.sort_values("timestamp").reset_index(drop=True)

print(df.shape)
print(df.isna().sum())          # 各列缺失数量
print(df.duplicated("timestamp").sum())  # 重复时间戳数量
print(df.describe())            # 量纲与异常量级初判

体检要回答三个问题:缺失有多少、重复有多少、数值范围是否物理合理。例如轴承温度出现 300 ℃、压力出现负值,多半是量程溢出或通信错帧,这类值应先标记为缺失再处理,而不是直接参与插值。

二、去除重复记录

网关重传常产生时间戳完全相同、数值略有差异的重复行。处理原则是“同一时刻只保留一条”,并优先保留后到的那条(通常更完整):

df = df.drop_duplicates(subset="timestamp", keep="last")
df = df.set_index("timestamp").sort_index()

若重复时间戳的数值差异很大,说明存在采集冲突,应记录冲突次数作为数据质量指标,而不是静默丢弃。

三、缺失值:先判断成因,再选插值或删除

缺失处理不能一刀切。短时掉线(如连续 1~3 个点)适合插值;长时间停机或检修造成的整段空白,插值会“编造”不存在的运行状态,应删除或标记为停机段。常用策略如下:

  • 线性插值:适用于温度、压力等缓变量,df["bearing_temp"].interpolate(method="linear", limit=3),limit 限制最多连续补 3 个点。
  • 时间插值:采样间隔不均匀时用 method="time",按真实时间距离加权,比按行号线性插值更准确。
  • 前向填充:仅用于状态类量(如运行/停机标志),不用于连续测量值。
  • 删除:连续缺失超过阈值(示例取 10 min)的区段整体剔除,并单独保存停机区间清单。
# 标记超长缺失段后删除
gap = df["vibration"].isna()
df["vibration"] = df["vibration"].interpolate(method="time", limit=3)
df = df.dropna(subset=["pressure", "vibration"])

四、平滑噪声:滑动平均的窗口选择

振动速度有效值受电机基频(1480/60 ≈ 24.7 Hz)与管路共振影响,单点波动大。滑动平均是最直接的平滑手段,但窗口过大会抹掉真实的冲击特征(如轴承早期故障的周期性冲击),因此窗口应远小于故障特征周期。示例取 5 点中心滑动平均:

df["vib_smooth"] = df["vibration"].rolling(window=5, center=True, min_periods=3).mean()

判断平滑是否合理,可对比平滑前后标准差:若标准差下降超过 60%,说明窗口可能过大,需检查是否把有意义的波动也压平了。对温度这类惯性大的量,窗口可放宽到 10~15 点;对电流则建议保留原始值用于谐波分析,只对趋势做平滑。

五、时间对齐:统一到同一时间栅格

泵组各传感器采样周期不同(压力 1 min、振动 10 s、温度 30 s),需要重采样到统一栅格。做法是先按目标频率聚合,再对齐:

rule = "1min"
aligned = pd.DataFrame({
    "pressure": df["pressure"].resample(rule).mean(),
    "vibration": df["vib_smooth"].resample(rule).mean(),
    "temp": df["bearing_temp"].resample(rule).mean(),
    "current": df["current"].resample(rule).mean(),
})
aligned = aligned.interpolate(method="time", limit=2)

重采样时用均值而非首值,可避免采样相位偏差;对齐后再做一次缺失检查,确保进入特征工程的数据是等间隔、无空洞的。

船舶泵组数据清洗流水线与关键判断 原始 CSV 压力/温度/振动/电流 数据体检 缺失/重复/量程异常 去除重复 同时间戳保留后到 缺失值分流 短缺口→时间插值(≤3点) 长缺口→删除并记录停机段 滑动平均平滑 振动窗口5点·中心对齐 温度窗口10~15点 时间对齐重采样 统一到 1 min 栅格 各列取均值后补缺 清洗后数据集 等间隔·无重复·无空洞 附数据质量报告 清洗质量核对(示例阈值) · 重复时间戳:0 条 · 剩余缺失率:< 1% · 时间间隔:全部为 60 s · 平滑后振动标准差下降:约 35%(<60%,未过度平滑) · 温度范围:20~85 ℃ 物理合理

六、结果核对与质量报告

清洗完成后必须核对,而不是“跑通即结束”。示例核对项包括:重复时间戳为 0;剩余缺失率低于 1%;时间间隔全部为 60 s;平滑后振动标准差下降约 35%,未超过 60% 的过度平滑警戒线;温度落在 20~85 ℃ 的物理合理区间。建议把上述指标连同删除的停机区间、插值点数一起写入一份数据质量报告,作为后续建模的数据版本依据。

插值与平滑都会改变原始信息。工程上应保留原始列,新增 vib_smooth 等派生列,并在报告中注明处理方法与参数(窗口、limit、重采样规则),保证结果可追溯、可复现。
常见误区:对整段停机空白做线性插值,会生成虚假的“正常运行”数据,直接污染剩余寿命估计;对振动信号使用过大窗口平滑,会抹掉轴承早期故障的冲击特征。缺失先判成因、平滑先看特征周期,是两条必须守住的底线。

至此,一份可用于特征提取的泵组数据集已经形成:时间等间隔、无重复、缺失受控、噪声适度抑制。后续的滚动统计、频域特征与健康指标计算,都应建立在这份经过核对的数据版本之上。