4. 数据清洗与预处理:缺失值处理、异常值检测、时间序列对齐、数据标准化
供应链控制塔的数据源通常来自 ERP、WMS、TMS、IoT 传感器等多个异构系统。原始数据在进入可视化看板之前,必须经过清洗与预处理,否则 KPI 指标将出现偏差、时间轴错位或量纲不可比。本章聚焦四个核心环节:缺失值处理、异常值检测、时间序列对齐、数据标准化。
4.1 缺失值处理
缺失值在供应链数据中普遍存在,原因包括传感器断连、人工录入遗漏、系统间同步延迟等。处理策略需根据缺失率、数据重要性及业务场景选择。
| 策略 | 适用场景 | 方法示例 | 注意事项 |
|---|---|---|---|
| 删除 | 缺失率 > 60%,或该字段非关键 | df.dropna(subset=['字段']) |
避免删除后样本量过小 |
| 均值/中位数填充 | 数值型字段,数据分布稳定 | df.fillna(df.median()) |
会降低方差,适合粗略估计 |
| 前向/后向填充 | 时间序列数据,缺失值前后相关 | df.fillna(method='ffill') |
适用于短期传感器中断 |
| 插值法 | 连续时间序列,趋势明显 | df.interpolate(method='linear') |
需确保时间索引有序 |
| 模型预测填充 | 重要字段,缺失率 < 20% | KNN / 随机森林回归 | 计算成本高,需验证精度 |
实践建议:在控制塔项目中,对库存量、订单行数等核心 KPI 字段优先使用插值法;对非关键描述字段(如备注)可直接删除或填充占位符。
4.2 异常值检测
异常值可能由设备故障、人为误操作或突发事件引起。检测方法分为统计法和距离法两类。
- Z-Score 法:适用于正态分布数据,通常取阈值 |Z| > 3 视为异常。
- IQR 四分位距法:适用于偏态分布,异常定义为 Q1 - 1.5×IQR 以下或 Q3 + 1.5×IQR 以上。
- 孤立森林:适用于高维数据,通过随机切割特征空间识别孤立点。
- DBSCAN 聚类:将密度低的点标记为异常,适合空间分布数据。
# 使用 IQR 法检测异常值示例
Q1 = df['lead_time'].quantile(0.25)
Q3 = df['lead_time'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers = df[(df['lead_time'] < lower_bound) | (df['lead_time'] > upper_bound)]
注意:异常值不一定是错误数据。例如,双十一期间订单量激增属于业务异常但真实有效,应保留并标记,而非直接删除。
4.3 时间序列对齐
不同数据源的时间戳粒度可能不一致:ERP 以天为单位,WMS 精确到秒,IoT 传感器每 5 分钟上报一次。对齐是时间序列分析的前提。
对齐步骤:
- 统一时区:将所有时间戳转换为 UTC 或业务所在时区。
- 重采样:按目标频率(如每小时、每天)聚合数据,常用方法包括求均值、求和、取最后值。
- 填充缺失时间点:重采样后可能出现空窗期,需结合 4.1 节方法填充。
- 索引排序:确保时间索引严格递增,避免后续计算错位。
# 时间序列对齐示例(按天重采样)
df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True)
df.set_index('timestamp', inplace=True)
df_aligned = df.resample('D').agg({
'order_qty': 'sum',
'inventory_level': 'last',
'lead_time': 'mean'
}).fillna(method='ffill')
4.4 数据标准化
控制塔看板常需在同一图表中展示多个量纲不同的指标(如订单金额、库存周转天数、准时交付率)。标准化可消除量纲影响,使指标可比。
| 方法 | 公式 | 输出范围 | 适用场景 |
|---|---|---|---|
| Z-Score 标准化 | \( z = \frac{x - \mu}{\sigma} \) | 均值 0,标准差 1 | 数据近似正态分布,需保留异常值相对位置 |
| Min-Max 归一化 | \( x' = \frac{x - min}{max - min} \) | [0, 1] | 有明确上下界,如百分比、评分 |
| Robust 标准化 | \( x' = \frac{x - median}{IQR} \) | 受异常值影响小 | 数据含较多异常值,需稳健缩放 |
| MaxAbs 缩放 | \( x' = \frac{x}{|max|} \) | [-1, 1] | 稀疏数据或已中心化的数据 |
# 使用 sklearn 进行标准化
from sklearn.preprocessing import StandardScaler, MinMaxScaler
# Z-Score 标准化
scaler = StandardScaler()
df['order_amount_z'] = scaler.fit_transform(df[['order_amount']])
# Min-Max 归一化
minmax = MinMaxScaler()
df['delivery_rate_norm'] = minmax.fit_transform(df[['delivery_rate']])
关键原则:标准化参数(均值、标准差、最小值、最大值)必须从训练集计算,再应用到验证集和测试集,避免数据泄露。在控制塔实时流场景中,建议使用滑动窗口动态更新标准化参数。
4.5 预处理流水线编排
在实际项目中,上述四个环节应组合为可复用的预处理流水线。推荐使用 sklearn.pipeline.Pipeline 或自定义函数链,确保每次数据接入时执行相同的转换逻辑。
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
pipeline = Pipeline([
('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())
])
clean_data = pipeline.fit_transform(raw_data)
工程提示:在控制塔项目中,建议将预处理流水线封装为独立的微服务或 Airflow DAG,每次新数据源接入时只需注册新的转换节点,无需修改核心逻辑。