2. PHM数据清洗与异常值处理实战
任务说明
本案例针对工业传感器时序数据,完成缺失值、噪声与异常点的清洗,输出可直接用于训练的数据集。核心处理链:滑动窗口均值滤波 → 3σ 准则标记异常 → 线性插值修复缺失与异常。输入为带缺失(NaN)和尖峰噪声的单通道传感器序列,输出为等长、无缺失、无异常点的干净序列。
环境与依赖
- Python 3.8+,依赖
numpy、pandas(pip install numpy pandas)。 - 无需其他框架,脚本可直接运行。
处理流程
完整实现
import numpy as np
import pandas as pd
def clean_sensor(series, window=5, sigma=3.0):
"""滑动窗口滤波 + 3σ异常标记 + 线性插值修复"""
s = pd.Series(series, dtype="float64")
# 1. 滑动窗口均值滤波(min_periods=1 保证边界与NaN不丢点)
smoothed = s.rolling(window=window, center=True, min_periods=1).mean()
# 2. 3σ 准则:基于滤波后序列的均值/标准差标记异常
mu, std = smoothed.mean(), smoothed.std(ddof=0)
lower, upper = mu - sigma * std, mu + sigma * std
mask = (smoothed < lower) | (smoothed > upper)
# 3. 将原始缺失值与异常点统一置为NaN,再线性插值
cleaned = s.copy()
cleaned[mask] = np.nan
cleaned = cleaned.interpolate(method="linear", limit_direction="both")
return cleaned, mask, (lower, upper)
if __name__ == "__main__":
# 构造含缺失与尖峰的示例数据
raw = [10.0, 10.2, np.nan, 10.1, 10.3, 50.0, 10.2, 10.1,
np.nan, 10.4, 10.2, 10.3, -30.0, 10.1, 10.2]
cleaned, mask, bounds = clean_sensor(raw, window=5, sigma=3.0)
print("异常点索引:", list(np.where(mask)[0]))
print("3σ区间:", tuple(round(b, 3) for b in bounds))
print("清洗后是否含NaN:", cleaned.isna().any())
print("清洗后序列:")
print(cleaned.round(3).tolist())
运行与验证
直接执行 python clean_sensor.py。判定通过条件:
清洗后是否含NaN输出False,说明缺失与异常点均被修复;异常点索引应包含尖峰位置(示例中索引 5 与 12);- 清洗后序列长度与输入一致,且数值落在 3σ 区间内,无 50.0、-30.0 等离群值。
若需接入真实数据,将 raw 替换为传感器 CSV 的某一列即可,例如 pd.read_csv("sensor.csv")["value"]。
关键点
center=True使滤波窗口居中,避免相位偏移;min_periods=1保证首尾与NaN位置不产生空洞。- 3σ 阈值基于滤波后序列计算,可抑制单个尖峰对均值/方差的污染。
limit_direction="both"确保序列首尾的缺失也能被插值填充,输出等长无缺失数据。