4. 数据预处理实战

田间部署的传感器很少能直接拿来用。以一套典型的温室/大田监测节点为例:空气温湿度、土壤含水率、光照强度四路信号,采样间隔 10 分钟,一天 144 条记录。真实数据里常见的问题包括:通信丢包造成的整段缺失、电池电压跌落导致的跳变、露水或灌溉引起的湿度尖峰、以及不同量纲参数无法直接比较。本节围绕一份模拟的真实田间数据,把清洗、缺失值处理、异常值检测和标准化四件事串成一条可复现的处理链。

一、先看清数据长什么样

假设原始 CSV 文件 field_node_01.csv 包含字段:timestamp, air_temp, air_hum, soil_moist, light。加载后先做三件事:统一时间戳为 datetime 并按时间排序、检查重复时间戳、统计各列缺失率。示例中 144 条记录里,soil_moist 缺失 9 条(6.3%),light 缺失 3 条,另有 2 条重复时间戳。重复记录保留第一条即可,因为同一时刻重复上报通常是网关重传。

import pandas as pd
df = pd.read_csv("field_node_01.csv", parse_dates=["timestamp"])
df = df.sort_values("timestamp").drop_duplicates("timestamp", keep="first")
print(df.isna().mean().round(3))

二、异常值检测:先定物理边界,再看统计离群

异常值检测建议分两层。第一层是物理可行域,用领域知识直接判定不可能值:空气温度合理范围约 -20~60 ℃,相对湿度 0~100%,土壤含水率 0~100%(体积含水率通常 0~60%),光照 0~150000 lx。超出即判为无效,置为缺失而不是直接删除整行,因为同一时刻其他通道可能仍然有效。

第二层是统计离群。对温度这类近似正态、变化平缓的序列,用滑动窗口中位数与 MAD(中位数绝对偏差)比用 3σ 更稳健,因为均值与标准差本身会被尖峰污染。判定式为 |x − median| > k × 1.4826 × MAD,k 取 3~4。示例中某条记录土壤含水率从 32% 突跳到 78% 又立刻回落,前后 1 小时内无灌溉事件,属于典型尖峰,应标记为异常。

对光照、土壤含水率这类有明显日周期或受灌溉事件驱动的序列,不要用全局阈值一刀切。更稳妥的做法是按小时分组计算局部中位数,或先做一阶差分再检测突变点,避免把真实的日出跃升误判为异常。

三、缺失值处理:按缺失机制选策略

缺失不是一律插值。短缺口(连续 ≤ 3 个采样点,即 ≤ 30 分钟)用时间线性插值即可;中等缺口(≤ 2 小时)可用同日同时段均值或前后窗口均值;长缺口(如设备离线半天以上)应保留为缺失并打标记,强行插值会制造虚假的平稳段,后续融合时误导权重分配。示例中 soil_moist 的 9 条缺失里有 6 条是连续 1 小时内的短缺口,用线性插值;剩余 3 条跨越 4 小时,保留 NaN 并新增 soil_moist_flag 列标记。

df["soil_moist"] = df["soil_moist"].interpolate(
    method="time", limit=3, limit_area="inside")
df["soil_moist_flag"] = df["soil_moist"].isna().astype(int)

四、标准化:为后续融合做准备

温度(℃)、湿度(%)、光照(lx)量纲差异巨大,直接进入加权融合会让数值大的通道主导结果。常用两种方式:Z-score 标准化 (x−μ)/σ 适合近似正态、无强异常的数据;Min-Max 归一化 (x−min)/(max−min) 适合有明确物理上下限的参数,如湿度、含水率。注意标准化参数必须只用训练段(如前 7 天)统计,再应用到验证段,否则会引入未来信息泄漏。示例中对温度用 Z-score,对湿度与含水率用 Min-Max,光照先取对数再标准化以压缩动态范围。

田间节点数据预处理链(示例:10 分钟采样,144 条/天) 原始 CSV 4 通道 × 144 条 缺失 12 条 / 重复 2 条 清洗 排序 · 去重 时间戳对齐 异常值检测 物理可行域过滤 滑动 MAD(k=3.5) → 置为 NaN 缺失值处理 短缺口 ≤3 点:线性插值 中缺口:同时段均值 长缺口:保留 + 标记 标准化 温度:Z-score 湿度/含水率:Min-Max 光照:log 后 Z-score 输出:干净数据集 4 通道标准化值 + 缺失标记列 + 异常标记列 关键约束 ① 标准化参数仅用训练段(前 7 天)统计,避免信息泄漏;② 异常置 NaN 而非删行,保留其他通道有效值; ③ 长缺口不强行插值,用 flag 列传递不确定性给后续融合环节。

五、结果如何判断处理是否到位

处理完不要只看代码跑通,要看几个可核对的指标:各列缺失率是否降到可接受水平(如 <2%)、异常标记数量是否与现场事件(灌溉、开窗、设备重启)在时间上对得上、标准化后各通道均值是否接近 0(Z-score)或落在 [0,1](Min-Max)、以及原始序列与处理后序列叠加对比时,真实趋势是否被保留而尖峰被削掉。示例中处理后温度通道均值 0.02、标准差 1.01,土壤含水率落在 [0.08, 0.94],异常标记 5 条,其中 3 条与记录的灌溉时段吻合,说明检测逻辑基本合理。

常见坑:把异常值直接删除会导致时间序列出现不等间隔,后续按固定步长做滑动平均或融合时会错位;用全局均值填充长缺口会人为压低方差,使融合权重高估该通道可靠性。正确做法是保留时间轴完整,用标记列显式表达数据质量。

完成上述四步后,得到的是带质量标记的标准化数据集,它才是后续滤波与多源融合的合格输入。预处理的价值不在于把数据“变好看”,而在于让每一个被修改的值都有依据、可追溯、可回退。