2. 工业设备传感器数据清洗与异常值处理

任务目标

本案例针对工业设备传感器采集的原始CSV数据,完成三类清洗任务:缺失值处理(均值填充)、重复值去除(完全重复行删除)、异常值处理(基于3σ准则识别并替换为边界值)。最终输出清洗后的数据集,并打印清洗前后记录数及异常值处理统计,用于验证数据质量改善效果。

环境与依赖

需要Python 3.8+,仅依赖pandas和numpy。若未安装,执行:

pip install pandas numpy

完整实现代码

以下代码为单文件实现,包含数据生成(模拟原始传感器数据)、清洗逻辑与验证输出。将代码保存为sensor_data_cleaning.py:

import pandas as pd
import numpy as np

# ---------- 1. 生成模拟原始传感器数据(含缺失、重复、异常) ----------
np.random.seed(42)
n = 200
time = pd.date_range('2024-01-01', periods=n, freq='min')
temp = 25 + 5 * np.sin(np.linspace(0, 8 * np.pi, n)) + np.random.normal(0, 0.8, n)
vib = 2.0 + 0.5 * np.random.randn(n)

# 注入10个缺失值
missing_idx = np.random.choice(n, 10, replace=False)
temp[missing_idx[:5]] = np.nan
vib[missing_idx[5:]] = np.nan

# 注入5个重复行(复制随机5行)
dup_idx = np.random.choice(n, 5, replace=False)
df_dup = df.iloc[dup_idx] if 'df' in locals() else None

df = pd.DataFrame({'timestamp': time, 'temperature': temp, 'vibration': vib})
df = pd.concat([df, df.iloc[dup_idx]], ignore_index=True)

# 注入6个异常值(超出3σ)
for _ in range(3):
    df.loc[np.random.choice(len(df)), 'temperature'] += np.random.choice([-1, 1]) * 15
for _ in range(3):
    df.loc[np.random.choice(len(df)), 'vibration'] += np.random.choice([-1, 1]) * 5

# 打乱顺序模拟真实采集
df = df.sample(frac=1, random_state=1).reset_index(drop=True)

print(f"原始数据形状: {df.shape}")
print(f"缺失值数量: {df.isnull().sum().sum()}")
print(f"重复行数量: {df.duplicated().sum()}")

# ---------- 2. 清洗流程 ----------
# 2.1 去除完全重复行
df_clean = df.drop_duplicates().reset_index(drop=True)

# 2.2 缺失值处理:数值列用均值填充
numeric_cols = ['temperature', 'vibration']
for col in numeric_cols:
    df_clean[col] = df_clean[col].fillna(df_clean[col].mean())

# 2.3 异常值处理:3σ准则,超出边界值替换为边界值
anomaly_count = {}
for col in numeric_cols:
    mean = df_clean[col].mean()
    std = df_clean[col].std()
    lower, upper = mean - 3 * std, mean + 3 * std
    mask = (df_clean[col] < lower) | (df_clean[col] > upper)
    anomaly_count[col] = int(mask.sum())
    df_clean.loc[mask, col] = np.clip(df_clean.loc[mask, col], lower, upper)

# ---------- 3. 验证输出 ----------
print("\n===== 清洗结果 =====")
print(f"清洗后数据形状: {df_clean.shape}")
print(f"清洗后缺失值数量: {df_clean.isnull().sum().sum()}")
print(f"清洗后重复行数量: {df_clean.duplicated().sum()}")
print(f"各列异常值处理数量: {anomaly_count}")
print("\n清洗后数据统计描述:")
print(df_clean[numeric_cols].describe().round(2))

运行方式

python sensor_data_cleaning.py

验证方法与通过标准

运行脚本后,观察输出并核对以下条件,全部满足即判定清洗流程正确:

  • 重复值去除:清洗后重复行数量为0,且清洗后行数 = 原始行数 − 原始重复行数。
  • 缺失值处理:清洗后缺失值数量为0,且填充值等于对应列的均值(可在输出统计中核对mean值)。
  • 异常值处理:清洗后temperature和vibration列的min与max均在各自mean ± 3*std范围内(输出统计中的std为清洗后标准差,边界由代码内部计算)。
  • 数据完整性:清洗后数据形状为(200, 3)——原始200条记录,注入5条重复被删除,无其他行丢失。

若输出中清洗后形状为(200, 3)、缺失值和重复值均为0、异常值处理数量为6(temperature和vibration各3个),则说明清洗流程按预期工作。

常见问题

  • 异常值边界计算:3σ准则使用清洗后(已去重、已填充缺失)的数据计算均值和标准差,避免重复行和NaN影响统计量。
  • 替换策略:异常值被裁剪到边界值(而非删除),保留数据点但消除极端影响,适用于后续趋势分析。
  • 扩展性:若传感器列更多,只需将列名加入numeric_cols列表即可自动处理。