4. 润滑油压温度趋势数据清洗与基线建立
为什么先清洗再建基线
圆锥破润滑系统的油压、油温原始趋势里混着三类“脏数据”:停机段(油泵停转,油压归零、油温缓慢下降)、启停瞬态(油压冲高、油温滞后上升)、以及传感器毛刺或单点跳变。若直接对全量数据求均值与分位数,基线会被停机段拉低、被瞬态拉宽,后续异常识别就会漏报或误报。本例的任务是:把多源数据对齐到统一时间轴,剔除无效点,按工况分段,只在“稳定正常运行”段上统计油压与油温的基线区间。
数据对象与对齐口径
假设已有 1 分钟粒度的历史记录,字段包括:ts(时间戳)、p_oil(润滑油压,MPa)、t_oil(油温,℃)、t_amb(环境温度,℃)、load(主电机电流占额定百分比,%)、pump_on(油泵运行信号 0/1)。
- 时间对齐:以 1 分钟为基准栅格,各测点按最近时间戳重采样;同一分钟内多条记录取中位数,避免单点毛刺污染对齐结果。
- 工况判定:
pump_on=1且load≥40%且连续稳定 ≥10 分钟,记为“稳定运行段”;pump_on=0为停机段;其余为过渡段。 - 异常点剔除:对稳定段内的油压、油温分别做滑动中位数偏差检验,偏差超过 3 倍稳健标准差(MAD 换算)判为离群点并剔除;同时剔除物理越界值(油压 ≤0 或 >0.6 MPa,油温 <20℃ 或 >75℃)。
- 基线统计:仅用清洗后的稳定段样本,取 P5~P95 作为正常区间,中位数作为基线中心;并按环境温度分档(<10℃、10~30℃、>30℃)分别统计,减少季节影响。
可执行的数据清洗与基线脚本
下面用 pandas 完成对齐、分段、剔除与基线统计。输入为一份 CSV(列名与上文一致),输出每个环境温度档的油压、油温基线区间,可直接作为后续异常识别的参照表。
import pandas as pd
import numpy as np
df = pd.read_csv("lube_history.csv", parse_dates=["ts"])
df = df.sort_values("ts").set_index("ts")
# 1) 1 min 栅格对齐,同分钟取中位数
grid = df.resample("1min").median(numeric_only=True)
# 2) 工况分段
pump = grid["pump_on"].fillna(0)
load = grid["load"]
stable = (pump == 1) & (load >= 40)
# 连续稳定 ≥10 min:滚动窗口内全为 True
stable_run = stable.rolling(10, min_periods=10).sum() == 10
grid["seg"] = np.where(pump == 0, "stop",
np.where(stable_run, "stable", "transit"))
# 3) 稳定段内离群点剔除(稳健 MAD)
def mad_mask(s, k=3.0):
med = s.rolling(31, center=True, min_periods=5).median()
mad = (s - med).abs().rolling(31, center=True, min_periods=5).median()
scale = 1.4826 * mad
return (s - med).abs() > k * scale.replace(0, np.nan)
for col, lo, hi in [("p_oil", 0.0, 0.6), ("t_oil", 20.0, 75.0)]:
bad = mad_mask(grid[col]) | (grid[col] <= lo) | (grid[col] > hi)
grid.loc[bad, col] = np.nan
# 4) 环境温度分档 + 基线统计
grid["amb_bin"] = pd.cut(grid["t_amb"], [-50, 10, 30, 80],
labels=["<10", "10-30", ">30"])
base = (grid[grid["seg"] == "stable"]
.groupby("amb_bin", observed=True)
.agg(p_med=("p_oil", "median"),
p_lo=("p_oil", lambda x: x.quantile(0.05)),
p_hi=("p_oil", lambda x: x.quantile(0.95)),
t_med=("t_oil", "median"),
t_lo=("t_oil", lambda x: x.quantile(0.05)),
t_hi=("t_oil", lambda x: x.quantile(0.95))))
print(base.round(2))
base.to_csv("lube_baseline.csv")
结果判读与使用约束
- 先看样本占比:若稳定段有效样本不足总时长的 40%,说明历史数据中停机或过渡过多,基线代表性不足,应延长取数窗口或补充数据。
- 看分档差异:若 >30℃ 档油温 P95 明显高于 10~30℃ 档(示例中约高 7℃),说明环境温度影响显著,必须分档使用,不能用一个全局区间。
- 看区间宽度:油压 P5~P95 跨度若超过 0.10 MPa,提示系统压力波动偏大,应回到泵出口压力、过滤器压差等测点复核,而不是直接放宽基线。
- 基线是“参照”不是“报警阈值”:后续异常识别应结合持续时间(如连续 5 min 越界)与负荷工况共同判断,避免单点越界误报。
清洗脚本中的窗口长度(31 点中位数、10 min 稳定判定)是示例取值,实际应按采样周期和破碎机启停节奏调整;调整后需重新核对稳定段样本占比是否合理。