分支语句通过动态控制异常处理策略与参数步长实现时序数据自适应清洗:依据“是否异常、类型、局部特征”选择插补方式、平滑窗口及阈值,分层应对连续缺失、孤立尖峰、低频漂移等场景,并支持时间上下文与多级容错。

分支语句本身不直接“实现平滑”,但它可以**动态控制异常处理的策略选择与参数步长**,从而适配时序数据在不同状态下的清洗需求。关键在于:把“是否异常”“异常类型”“数据局部特征”作为分支条件,再据此切换插补方式、平滑窗口大小、异常判定阈值等清洗动作的粒度(即“步长”)。
识别时序异常状态并分层判断
不能对整段序列用固定标准。需先用分支逻辑区分典型场景:
- 连续缺失段(如传感器断线3小时)→ 触发长周期插补(如线性/季节性分解填充),跳过平滑
- 孤立尖峰异常(单点电压突增至2倍均值)→ 启用小窗口中值滤波(步长=3或5)
- 低频漂移型噪声(缓慢偏移导致基线倾斜)→ 切换为大窗口Savitzky-Golay平滑(步长=15–31)
- 无异常→ 直接透传,避免冗余计算
用if-elif-else控制平滑参数步长
以Python为例,结合scipy.signal.savgol_filter和statsmodels.tsa.seasonal.STL:
from statsmodels.tsa.seasonal import STL
from scipy.signal import savgol_filter
import numpy as np
<p>def adaptive_smooth(series, window_length):</p><h1>先做基础异常检测(例如IQR法)</h1><pre class="brush:php;toolbar:false;">q1, q3 = np.percentile(series, [25, 75])
iqr = q3 - q1
lower, upper = q1 - 1.5*iqr, q3 + 1.5*iqr
outliers = (series upper)
if outliers.sum() == 0:
return series # 无异常,不处理
elif outliers.sum() == 1 and np.diff(np.where(outliers)[0]).size == 0:
# 孤立单点异常 → 小窗口中值滤波(步长=3)
return series.rolling(3, center=True).median().fillna(series)
elif outliers.sum() > 5 and np.max(np.diff(np.where(outliers)[0])) <p></p>嵌套分支支持多级恢复逻辑
当某步平滑失败(如窗口太大报错),可用try-except嵌套分支兜底:
- 外层if判断数据形态 → 决定主清洗路径
- 内层try执行高阶平滑 → 成功则返回
- except捕获ValueError/ZeroDivisionError → 切换至更保守步长(如从wl=31降为wl=7)
- 再except → 回退至均值填充
结合时间索引做条件分支更精准
时序数据的“上下文”很重要。可基于时间特征分支:
- 工作日 9:00–17:00 → 使用业务周期步长(如电力负荷用15分钟粒度)
- 凌晨时段 → 切换为更宽松的异常阈值(因基线本就低)
- 节假日标记为True → 跳过周期性分解,改用移动平均
示例片段:
if series.index.hour.isin(range(9, 17)).all() and not is_holiday(series.index.date[0]):
smooth_func = lambda x: savgol_filter(x, window_length=15, polyorder=2)
elif series.index.hour.isin(range(0, 6)).all():
smooth_func = lambda x: x.ewm(span=24).mean()
else:
smooth_func = lambda x: x.rolling(7).mean()
不复杂但容易忽略:分支不是为了炫技,而是让平滑“有感知”。每一步长切换都应对应一个可解释的时序行为假设,否则就是盲目调参。










