2. 处理缺失值
任务说明
本案例针对一组包含缺失值的高频数值型时间序列数据,实现基于中位数的缺失值填充策略。与均值填充相比,中位数对异常值不敏感,更适合分布偏斜或存在离群点的高频数据场景。你需要完成以下工作:构造含缺失值的示例数据集,实现中位数填充函数,并验证填充结果的有效性。
实现方案
采用Python标准库与NumPy完成核心逻辑。首先构造一个包含随机缺失值的时间序列数组,然后计算非缺失值的中位数,用该中位数替换所有缺失位置。为便于验证,代码会输出缺失值数量、计算得到的中位数以及填充后数组的基本统计信息。
import numpy as np
import pandas as pd
# 设置随机种子保证可复现
np.random.seed(42)
# 1. 构造含缺失值的时间序列数据(模拟高频传感器读数)
n = 100
timestamps = pd.date_range('2024-01-01', periods=n, freq='s')
values = np.random.normal(loc=50, scale=8, size=n).round(2)
# 人为引入异常值(使分布偏斜,体现中位数优势)
values[10] = 500.0
values[25] = -200.0
# 随机删除15%的数据点作为缺失值
missing_idx = np.random.choice(n, size=int(n*0.15), replace=False)
values_with_nan = values.copy()
values_with_nan[missing_idx] = np.nan
# 2. 中位数填充实现
def median_fill(series):
"""用非缺失值的中位数填充缺失值"""
arr = np.asarray(series, dtype=np.float64)
median_val = np.nanmedian(arr)
filled = np.where(np.isnan(arr), median_val, arr)
return filled, median_val
# 执行填充
filled_values, median_val = median_fill(values_with_nan)
# 3. 输出验证信息
print(f"原始数据长度: {n}")
print(f"缺失值数量: {np.isnan(values_with_nan).sum()}")
print(f"缺失比例: {np.isnan(values_with_nan).sum()/n:.1%}")
print(f"计算得到的中位数: {median_val:.2f}")
print(f"填充后缺失值数量: {np.isnan(filled_values).sum()}")
print(f"填充后均值: {filled_values.mean():.2f}")
print(f"填充后标准差: {filled_values.std():.2f}")
# 4. 对比:均值填充(用于说明中位数优势)
mean_val = np.nanmean(values_with_nan)
mean_filled = np.where(np.isnan(values_with_nan), mean_val, values_with_nan)
print(f"\n对比-均值填充:")
print(f"均值: {mean_val:.2f}")
print(f"均值填充后整体均值: {mean_filled.mean():.2f}")
print(f"中位数填充后整体均值: {filled_values.mean():.2f}")
运行方式
确保已安装NumPy和Pandas库。将上述代码保存为median_fill_demo.py,在终端执行python median_fill_demo.py即可。
验证方法与判定标准
运行代码后,观察输出结果:
- “填充后缺失值数量”必须为0,证明所有缺失位置均已被替换;
- “计算得到的中位数”应接近原始正常数据的中心位置(约50),而非被异常值拉偏;
- 对比均值填充结果,中位数填充后的整体均值应更接近原始正常数据的均值(约50),而均值填充因受500和-200两个异常值影响,整体均值会明显偏离;
- 若上述条件满足,则判定中位数填充实现正确且有效。
预期输出
由于设置了随机种子,每次运行结果一致。预期输出中“填充后缺失值数量”为0,“计算得到的中位数”约为50.00(实际值取决于随机删除后保留的数据),中位数填充后的整体均值接近50,而均值填充后的整体均值会因异常值影响明显偏离(可能超过55或低于45)。