Python基于历史观测值填补时间序列缺失值的优化方案咨询
问题1:更优雅的现有场景实现
你原有的硬编码多条件判断写法可以大幅简化,核心逻辑是按填补优先级从高到低,依次用对应偏移的历史值填充空值,已填充的值不会被后续低优先级值覆盖,用pandas原生的fillna方法就能实现,不需要手动编写大量条件判断,和你原有逻辑完全等价:
import pandas as pd import numpy as np # 确保原始数据的时间索引是正序 proxy = proxy.sort_index() filled = proxy['mains_1'].copy() # 按填补优先级从高到低排列偏移周期 fill_order = ['7D', '14D', '21D', '1D', '2D', '1H'] for freq in fill_order: # 仅填充空值,已有有效值的位置保持不变 filled = filled.fillna(proxy['mains_1'].shift(freq=freq)) # 兜底用全数据集均值填充剩余空值 filled = filled.fillna(proxy['mains_1'].mean()) # 合并回原数据集 proxy['filled'] = filled
问题2:通用可配置的填补方案
可以封装为通用函数,支持自定义回溯周期优先级、自定义兜底规则,示例实现如下:
def fill_timeseries_missing( df: pd.DataFrame, target_col: str, fill_priority_freq: list, # 填补优先级从高到低的偏移周期列表,例如['7D','14D','1D'] fallback_strategy = 'mean', # 兜底策略,支持'mean'/'median',或传入自定义计算函数 fallback_window: str = None # 兜底计算的时间窗口,例如'60D'代表过去两个月均值,None为全量计算 ) -> pd.Series: """ 时间序列缺失值按优先级填充通用工具 """ if not isinstance(df.index, pd.DatetimeIndex): raise TypeError("DataFrame索引必须为DatetimeIndex类型") df = df.sort_index() filled = df[target_col].copy() # 按优先级依次用偏移历史值填充 for freq in fill_priority_freq: filled = filled.fillna(df[target_col].shift(freq=freq)) # 处理兜底填充逻辑 if filled.isna().any(): if callable(fallback_strategy): fallback_val = fallback_strategy(df[target_col]) elif fallback_strategy == 'mean': fallback_val = df[target_col].mean() if fallback_window is None else df[target_col].rolling(fallback_window).mean() elif fallback_strategy == 'median': fallback_val = df[target_col].median() if fallback_window is None else df[target_col].rolling(fallback_window).median() else: raise ValueError("不支持的兜底策略,可传入'mean'/'median'或自定义可调用对象") filled = filled.fillna(fallback_val) return filled
使用示例
如果需要实现「优先用3周前、4周前同期值,兜底用过去2个月均值」的需求,直接调用即可:
proxy['filled'] = fill_timeseries_missing( df=proxy, target_col='mains_1', fill_priority_freq=['21D', '28D'], fallback_strategy='mean', fallback_window='60D' )
内容的提问来源于stack exchange,提问作者Ashkan Lotfipoor
相关产品推荐
相关产品推荐

