2、数据预处理基础:时间戳对齐、异常值检测与缺失值插补
各位同学,欢迎来到数据预处理这一章。说实话,我在嵌入式气象站项目里踩过最多的坑,不是传感器选型,也不是通信协议,而是——数据预处理。你想想看,传感器采集回来的原始数据,就像刚从泥里挖出来的土豆,不洗干净根本没法下锅。
这一章我们聚焦三个核心问题:时间戳对齐、异常值检测、缺失值插补。这三个环节做好了,后面的融合算法才能跑得稳。我个人习惯把预处理叫做「数据清洗三部曲」,少一步都不行。
2.1 时间戳对齐:让不同传感器「说同一种语言」
先问一个问题:风速传感器每1秒采集一次,温湿度传感器每2秒采集一次,气压传感器每5秒采集一次。它们的数据到了融合模块,时间点对不上,怎么办?
这就是时间戳对齐要解决的问题。说白了,就是要把不同采样率的数据,统一到同一个时间基准上。
2.1.1 常见对齐策略
我在项目中用过三种方法,各有适用场景:
| 方法 | 原理 | 适用场景 |
|---|---|---|
| 最近邻对齐 | 取时间差最小的采样点 | 采样率接近、允许微小偏差 |
| 线性插值对齐 | 在两个采样点之间线性估算 | 采样率差异大、需要平滑过渡 |
| 重采样对齐 | 统一到固定频率(如1Hz) | 多传感器融合、固定时间窗口 |
我个人最常用的是重采样对齐。举个例子,风速是10Hz,温湿度是1Hz,我会把温湿度数据通过线性插值,也变成10Hz。这样所有数据都在同一个时间轴上,后续处理就简单了。
核心原则:对齐后的时间戳,必须保证数据完整性。不要为了对齐而丢掉有效数据。
2.1.2 代码实现:重采样对齐
下面这段代码,是我在某个气象站项目里实际用过的。它能把不同采样率的数据统一到1Hz:
import pandas as pd
import numpy as np
def resample_alignment(data_dict, target_freq='1S'):
"""
将多个传感器数据重采样到统一频率
data_dict: {'sensor_name': DataFrame with datetime index}
target_freq: 目标频率,如 '1S' 表示1秒
"""
aligned_data = {}
for name, df in data_dict.items():
# 先确保时间索引是datetime类型
df.index = pd.to_datetime(df.index)
# 重采样并线性插值
resampled = df.resample(target_freq).interpolate(method='linear')
aligned_data[name] = resampled
return aligned_data
# 使用示例
wind_data = {'time': ['2024-01-01 00:00:00', '2024-01-01 00:00:01'], 'speed': [3.2, 3.5]}
temp_data = {'time': ['2024-01-01 00:00:00', '2024-01-01 00:00:02'], 'temp': [22.1, 22.3]}
# 实际使用时需要构建DataFrame并设置时间索引
我的经验:重采样时注意边界处理。如果目标时间点落在数据范围之外,建议用前向填充或后向填充,不要用插值——插值会「无中生有」,产生虚假数据。
2.2 异常值检测:揪出那些「离谱」的数据
传感器不是完美的。电磁干扰、通信丢包、传感器老化,都会产生异常值。我记得有一次,风速传感器突然跳出一个99.9m/s的值——这都赶上12级台风了,可当时明明是个大晴天。
异常值检测,就是要把这些「离谱」的数据找出来。我常用的方法有两种:3σ原则和IQR方法。
2.2.1 3σ原则:适合正态分布的数据
3σ原则基于正态分布假设。简单说,如果数据服从正态分布,那么99.7%的数据会落在均值±3个标准差范围内。落在范围外的,就是异常值。
公式很简单:
- 上界 = μ + 3σ
- 下界 = μ - 3σ
- 超出上下界的,标记为异常
但要注意——3σ原则对异常值本身很敏感。如果数据里已经混入了几个很大的异常值,均值和标准差都会被拉偏,导致检测失效。我遇到过这种情况,后来改用「迭代3σ」:先剔除明显异常,再重新计算均值和标准差,反复几次。
2.2.2 IQR方法:更稳健的选择
IQR(四分位距)方法不依赖正态分布假设,对异常值更鲁棒。它的原理是:
- 计算数据的Q1(25%分位数)和Q3(75%分位数)
- IQR = Q3 - Q1
- 下界 = Q1 - 1.5 × IQR
- 上界 = Q3 + 1.5 × IQR
超出上下界的,就是异常值。这个1.5倍是经验值,我在项目中一般用1.5,但如果数据波动特别大,会放宽到3倍。
对比总结:
- 数据接近正态分布 → 用3σ原则
- 数据分布未知或有偏 → 用IQR方法
- 数据量小(<30个点)→ 两种方法都不太可靠,建议人工检查
2.2.3 代码实现:两种异常检测方法
import numpy as np
def detect_outliers_3sigma(data):
"""基于3σ原则检测异常值"""
mean = np.mean(data)
std = np.std(data)
upper = mean + 3 * std
lower = mean - 3 * std
outliers = (data < lower) | (data > upper)
return outliers, lower, upper
def detect_outliers_iqr(data, multiplier=1.5):
"""基于IQR方法检测异常值"""
q1 = np.percentile(data, 25)
q3 = np.percentile(data, 75)
iqr = q3 - q1
lower = q1 - multiplier * iqr
upper = q3 + multiplier * iqr
outliers = (data < lower) | (data > upper)
return outliers, lower, upper
# 示例数据
sensor_data = np.array([22.1, 22.3, 22.0, 22.2, 99.9, 22.1, 22.4])
outliers_3s, _, _ = detect_outliers_3sigma(sensor_data)
outliers_iqr, _, _ = detect_outliers_iqr(sensor_data)
print(f"3σ检测到的异常索引: {np.where(outliers_3s)[0]}")
print(f"IQR检测到的异常索引: {np.where(outliers_iqr)[0]}")
避坑指南:我曾经在一个项目中,直接用3σ原则检测风速数据,结果把正常的阵风(比如8m/s)也标记为异常了。为什么?因为那段时间平均风速只有2m/s,标准差很小,8m/s确实超过了3σ。但气象学上,阵风达到4倍平均风速是正常的。所以——异常值检测一定要结合领域知识,不能纯靠统计。
2.3 缺失值插补:把「断掉」的数据接起来
传感器偶尔会掉线,通信偶尔会丢包。数据出现缺失是常态,不是异常。处理缺失值,我常用的方法是线性插值和前向填充。
2.3.1 线性插值:适合缓慢变化的数据
线性插值假设两个已知点之间的变化是线性的。对于温度、气压这类变化缓慢的物理量,效果很好。
公式:y = y₁ + (y₂ - y₁) × (x - x₁) / (x₂ - x₁)
说白了,就是在两个点之间画一条直线,缺失点就在这条直线上。
2.3.2 前向填充:适合快速变化或离散数据
前向填充(Forward Fill)就是用上一个有效值填充缺失值。比如风向数据,变化很快,用线性插值反而会「制造」出实际不存在的风向。这时候用前向填充更合理。
我个人的经验法则:
- 连续变化量(温度、气压、湿度)→ 线性插值
- 离散量或突变量(风向、降雨、开关量)→ 前向填充
- 缺失连续超过5个点 → 两种方法都不建议,需要标记为「数据不可用」
2.3.3 代码实现:两种插补方法
import pandas as pd
import numpy as np
# 构造带缺失值的数据
time = pd.date_range('2024-01-01 00:00:00', periods=10, freq='1S')
temp = [22.1, 22.3, np.nan, np.nan, 22.6, 22.8, np.nan, 23.0, 23.1, 23.2]
df = pd.DataFrame({'temp': temp}, index=time)
# 线性插值
df_linear = df.interpolate(method='linear')
print("线性插值结果:")
print(df_linear)
# 前向填充
df_ffill = df.ffill()
print("\n前向填充结果:")
print(df_ffill)
我的小技巧:在实际项目中,我不会只用一种方法。我会先看缺失值的分布——如果缺失是随机的、零散的,用线性插值;如果缺失是连续的(比如传感器掉线了5秒),我会先用前向填充,再用线性插值平滑一下。嗯,这算是我自己摸索出来的「组合拳」。
2.4 本章小结
数据预处理看起来琐碎,但它是整个数据融合流程的基石。我见过太多项目,算法模型调得再好,预处理没做好,结果一塌糊涂。
记住三个要点:
- 时间戳对齐:重采样+插值,让所有传感器「步调一致」
- 异常值检测:3σ原则适合正态分布,IQR方法更稳健,但都要结合领域知识
- 缺失值插补:线性插值适合连续量,前向填充适合离散量,别搞混了
下一章,我们会把这些预处理后的数据,真正送入融合算法。到时候你会发现——预处理做得越扎实,融合效果就越稳。这是我在无数个熬夜调试的夜晚,用血泪换来的经验。
公众号:蓝海资料掘金营,微信deep3321