🧹 第4课 · 让脏数据变得干净可靠
库存数据中常见空值,例如 入库量、出库日期 等字段缺失。两种主流策略:
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 删除缺失行 | 缺失极少 (<1%) | 简单无偏 | 样本减少 |
| 均值填充 | 正态分布数值 | 保持均值 | 降低方差 |
| 中位数填充 | 偏态分布 | 稳健 | 忽略分布形状 |
| 前向填充 (ffill) | 时间序列库存 | 利用时序趋势 | 可能传播异常 |
import pandas as pd import numpy as np df = pd.read_csv('inventory.csv') # 1. 查看缺失 print(df.isnull().sum()) # 2. 删除缺失比例 > 50% 的列 df.dropna(thresh=len(df)*0.5, axis=1, inplace=True) # 3. 数值列用中位数填充 num_cols = ['stock_qty', 'inbound_qty'] df[num_cols] = df[num_cols].fillna(df[num_cols].median()) # 4. 类别列用众数填充 df['warehouse'] = df['warehouse'].fillna(df['warehouse'].mode()[0]) # 5. 时间序列向前填充 df['record_date'] = pd.to_datetime(df['record_date']) df.sort_values('record_date', inplace=True) df['daily_sales'].fillna(method='ffill', inplace=True)
重复记录会导致库存计数虚高,影响预测。通常保留第一条,删除其余。
# 检测重复行 dup_rows = df.duplicated().sum() print(f"重复行数: {dup_rows}") # 删除完全重复 df.drop_duplicates(inplace=True) # 基于特定列去重 (保留最后一条) df.drop_duplicates(subset=['sku', 'date'], keep='last', inplace=True) # 查看重复值比例 dup_rate = df.duplicated().mean() * 100 print(f"重复比例: {dup_rate:.2f}%")
库存数据中异常值常由录入错误、传感器故障引起。常用方法:
| 方法 | 阈值 | 处理方式 | 适用 |
|---|---|---|---|
| Z-score | |Z| > 3 | 删除 / 封顶 | 近似正态 |
| IQR | 1.5倍IQR | 截尾 / 替换 | 偏态分布 |
| 分位数截断 | 1% ~ 99% | 截断 | 极值敏感 |
| 领域规则 | 业务上下限 | 修正为边界 | 强业务知识 |
def detect_outliers_iqr(series): Q1 = series.quantile(0.25) Q3 = series.quantile(0.75) IQR = Q3 - Q1 lower = Q1 - 1.5 * IQR upper = Q3 + 1.5 * IQR return (series < lower) | (series > upper) outliers = detect_outliers_iqr(df['stock_qty']) print(f"异常值数量: {outliers.sum()}") # 处理:用中位数替换异常 median_val = df['stock_qty'].median() df.loc[outliers, 'stock_qty'] = median_val # 或者直接删除异常行 df_clean = df[~outliers].copy()