You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用跨年度对应日期均值填补时间序列的长周期缺失值?

用同期日期均值填补时间序列缺失值

问题描述

我拥有2015-2022年的日度时间序列数据集:

  • 2015-2018年仅包含1-6月数据,7-12月全为NA
  • 2019-2022年数据完整

需要利用2019-2022年的数据,计算缺失月份对应日期的均值,填补NA值。

模拟数据集

以下是模拟场景的代码:2019年7-8月全为缺失值,需要用2020、2021年对应日期的均值填补;此前尝试过pandas插值方法,但因缺失周期过长效果不佳。

import numpy as np
import pandas as pd

np.random.seed(1)

rows,cols = 1000,3 # 数据集共1000行,对应2019-01-01至2021-09-26的日度数据
data = np.random.rand(rows,cols) 
tidx = pd.date_range('2019-01-01', periods=rows, freq='D') 
df = pd.DataFrame(data, columns=['a','b','c'], index=tidx) # 包含3个数据列
date_list =pd.date_range(start='2019-07-01', end='2019-08-31') 
df[df.index.isin(date_list)] = np.nan # 2019年7-8月全为缺失,2020、2021年对应月份有数据

print(df)

解决方案

核心逻辑是通过月-日特征匹配不同年份的同一天,用后续年份的同期均值填补缺失。

步骤1:提取月-日标识

为每个日期生成month_day列(格式MM-DD),用于跨年份匹配同一天:

df['month_day'] = df.index.strftime('%m-%d')

步骤2:计算同期日期均值

筛选2020-2021年的数据,按month_day分组计算各列的均值:

# 筛选2020和2021年的有效数据
year_mask = (df.index.year >= 2020) & (df.index.year <= 2021)
daily_means = df[year_mask].groupby('month_day')[['a','b','c']].mean()

步骤3:填补缺失值

定位2019年7-8月的缺失行,通过month_day匹配均值完成填补:

# 定位需要填补的缺失行
fill_mask = df.index.isin(date_list)
# 按月-日匹配均值,填充缺失值
df.loc[fill_mask, ['a','b','c']] = df.loc[fill_mask].apply(
    lambda row: daily_means.loc[row['month_day']], axis=1
)

步骤4:清理辅助列

填补完成后,可删除用于匹配的month_day列:

df.drop('month_day', axis=1, inplace=True)

完整可运行代码

import numpy as np
import pandas as pd

np.random.seed(1)

rows,cols = 1000,3 
data = np.random.rand(rows,cols) 
tidx = pd.date_range('2019-01-01', periods=rows, freq='D') 
df = pd.DataFrame(data, columns=['a','b','c'], index=tidx)
date_list =pd.date_range(start='2019-07-01', end='2019-08-31') 
df[df.index.isin(date_list)] = np.nan

# 提取月-日标识
df['month_day'] = df.index.strftime('%m-%d')

# 计算2020-2021年同期日期均值
year_mask = (df.index.year >= 2020) & (df.index.year <= 2021)
daily_means = df[year_mask].groupby('month_day')[['a','b','c']].mean()

# 填补缺失值
fill_mask = df.index.isin(date_list)
df.loc[fill_mask, ['a','b','c']] = df.loc[fill_mask].apply(
    lambda row: daily_means.loc[row['month_day']], axis=1
)

# 删除辅助列
df.drop('month_day', axis=1, inplace=True)

# 查看填补后的结果
print(df.loc[date_list])

内容的提问来源于stack exchange,提问作者dev-charodeyka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 02:55:24