时间序列中特定年份整段缺失值的填充方法 以Kaggle日降雨量数据集为例
全年段缺失日降雨量序列的合理填充方案
首先明确两种你已经尝试过的方法失效的核心原因:
- 时间线性插值的本质问题:
interpolate(method='time')是将相邻两个非缺失端点的差值按时间权重均匀分摊到缺失段,默认序列是连续平滑变化的。但日降雨量是强季节性、非平稳的气象序列,完全不符合这个前提——它会把2008年末到2010年初的差值拉成一条斜直线,自然会算出远超意大利夏季实际降雨水平的虚高值。 - 相邻年份同日期取均值的本质问题:这个思路默认同日历日的降雨量是稳定的确定性值,但日降雨是强随机事件,比如2008年7月15日的50mm暴雨、2010年7月15日的无雨,两者均值得到的25mm属于完全脱离实际的“虚构值”,还会人为把夏季极高的无雨占比(85%以上)稀释,破坏降雨的真实分布特征。
适合新手在Kaggle竞赛中落地的填充方案
按照实现难度从低到高排序:
1. 基于同日历日经验分布的抽样填充
这是最符合气象常识、实现成本最低的方法,核心思路是完全规避全局统计、全局插值的思路,保留日降雨的季节性分布特征:
- 第一步对齐时间周期:给所有观测值标记对应的年内第几天(dayofyear),处理好闰年的日期对齐问题,不管观测值来自哪一年,把同个年内位置的所有历史降雨量归为一组,形成每个日历日的经验分布——比如所有观测到的7月15日的降雨量凑成一组,这个组的分布天然就符合“绝大多数值在0-1mm、少量超过10mm的暴雨尖峰”的意大利夏季特征。
- 填充2009年的缺失值时,不要直接取同组的均值,而是结合两个相邻年份同日期的观测值的分位数位置,从对应组的经验分布里抽样取值:比如2008年7月15日的降雨量在所有历史同日期值里的分位是0.2,2010年7月15日的同日期值分位是0.3,就从0.2-0.3的分位区间里随机抽一个值作为2009年7月15日的填充值,既保留相邻年份的年际波动关联,又不会把随机暴雨尖峰平滑成虚高的均值。
- 核心约束:填充后每一天的0值占比,要和同日历日的历史分布完全一致,不能稀释无雨日的比例。
这个方法输出的2009年降雨量分布形态,会和2008年等正常年份的观测分布完全一致,不会出现插值后夏季普遍30mm以上的离谱结果。
2. 保留降雨自相关特征的优化填充
在上面的基础方法上做优化,进一步贴合降雨的实际生成规律:
- 不要对每一天做独立抽样,而是参考相邻年份的连续降雨过程特征:降雨不是单天跳变的独立事件,通常会形成连续2-3天的降雨过程,过程的累计雨量、持续时长都是有规律的。填充时可以直接参考2008、2010年同时间段的连续降雨事件结构,把对应的事件值匹配到2009年的对应位置,避免出现“单日暴雨、次日归零、第三日又暴雨”的不符合实际的跳变。
- 增加全年累计值的合理性约束:填充完成后校验2009年的年累计降雨量,确保它落在所有已有正常年份年累计值的5%-95%分位区间内,避免出现全年雨量极端偏高/偏低的离谱结果。
明确需要规避的操作
- 绝对不要使用全序列均值填充、全局线性时间插值这类通用方法,这类方法本质上没有考虑日降雨的年周期季节性特征,输出结果会完全脱离实际气象规律。
- 不要直接用相邻两年同日期的算术均值做填充,这种方法会把强随机的降雨尖峰平滑掉,同时破坏无雨日的占比分布,让填充结果的统计特征和真实降雨出现明显偏差。
内容的提问来源于stack exchange,提问作者carminoplata
相关产品推荐
相关产品推荐

