4. 处理缺失值
任务说明
本案例处理时间序列数据中的缺失值,采用前向填充(ffill)与后向填充(bfill)两种策略。输入为一组带时间戳的观测序列,其中部分时间点数据缺失;目标是生成两个完整序列:一个用最近的有效观测值向后填充(前向填充),另一个用下一个有效观测值向前填充(后向填充),并输出填充结果供下游分析使用。
数据与依赖
使用Python标准库csv与datetime实现,不依赖第三方库。输入文件sensor_data.csv包含两列:timestamp(ISO格式)与value(浮点数,缺失为空字符串)。样例数据如下:
timestamp,value
2025-01-01 00:00:00,21.5
2025-01-01 00:01:00,
2025-01-01 00:02:00,
2025-01-01 00:03:00,22.1
2025-01-01 00:04:00,
2025-01-01 00:05:00,21.9
实现代码
import csv
from datetime import datetime
def load_data(path):
rows = []
with open(path, newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
for r in reader:
ts = datetime.strptime(r['timestamp'], '%Y-%m-%d %H:%M:%S')
val_str = r['value'].strip()
val = float(val_str) if val_str else None
rows.append({'ts': ts, 'val': val})
return rows
def fill_missing(rows):
ffill = []
bfill = []
last_valid = None
n = len(rows)
# 前向填充:用前一个有效值填充
for r in rows:
if r['val'] is not None:
last_valid = r['val']
ffill.append(last_valid)
# 后向填充:用后一个有效值填充
next_valid = None
for i in range(n - 1, -1, -1):
if rows[i]['val'] is not None:
next_valid = rows[i]['val']
bfill.insert(0, next_valid)
return ffill, bfill
def write_output(path, rows, ffill, bfill):
with open(path, 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['timestamp', 'original', 'ffill', 'bfill'])
for i, r in enumerate(rows):
orig = '' if r['val'] is None else f"{r['val']:.1f}"
ff = '' if ffill[i] is None else f"{ffill[i]:.1f}"
bf = '' if bfill[i] is None else f"{bfill[i]:.1f}"
writer.writerow([r['ts'].strftime('%Y-%m-%d %H:%M:%S'), orig, ff, bf])
if __name__ == '__main__':
data = load_data('sensor_data.csv')
ff, bf = fill_missing(data)
write_output('filled_output.csv', data, ff, bf)
print("处理完成,结果已写入 filled_output.csv")
运行与验证
将上述代码保存为fill_missing.py,与sensor_data.csv置于同一目录,执行:
python fill_missing.py
程序读取输入文件,对缺失值分别执行前向与后向填充,将结果写入filled_output.csv。验证方法:打开输出文件,检查每个缺失位置——ffill列应等于该位置之前最近的非空值;bfill列应等于该位置之后最近的非空值。若序列开头无前值,则ffill为空;若结尾无后值,则bfill为空。
针对样例输入,预期输出文件内容如下(确定性推导结果):
timestamp,original,ffill,bfill
2025-01-01 00:00:00,21.5,21.5,21.5
2025-01-01 00:01:00,,21.5,22.1
2025-01-01 00:02:00,,21.5,22.1
2025-01-01 00:03:00,22.1,22.1,22.1
2025-01-01 00:04:00,,22.1,21.9
2025-01-01 00:05:00,21.9,21.9,21.9
判定标准:输出文件与上述逐行一致,且程序无异常退出,即视为通过。