多索引DataFrame按国家时序分组 基于就近可用值补全NaN缺失值
多索引DataFrame按国家分组的时序自适应填充实现
实现思路
你需要的填充规则可以通过两层连续填充覆盖,不需要手动为每个国家指定填充方向:
- 对组内靠前位置存在有效数值的场景:沿时间轴做前向填充(forward-fill),用缺失位置之前最近的有效值补全后置缺失
- 对组内靠前位置全部为缺失、第一个有效值出现在时序中后段的场景:在前向填充完成后,对剩余的、位于首个有效值之前的缺失做后向填充(backward-fill),用缺失位置之后最近的有效值补全前置缺失
操作步骤
- 先确认多索引层级关系,将
country作为分组维度、date作为时序排序维度,分组前对每个国家的组内行按日期升序排序,避免时序错位导致填充取错值 - 使用
groupby按country层级拆分每个国家的独立时序块 - 对每个时序块依次调用pandas原生的
ffill()、bfill()方法完成填充,无需自定义处理函数,性能更优
可直接复用的代码
import pandas as pd import numpy as np # 构造和示例完全一致的原始多索引DataFrame index = pd.MultiIndex.from_tuples([ ("BRA", "1959-01-01"), ("BRA", "1960-01-01"), ("BRA", "1961-01-01"), ("BRA", "1962-01-01"), ("COL", "1960-01-01"), ("COL", "1961-01-01"), ("COL", "1962-01-01"), ("COL", "1963-01-01") ], names=["country", "date"]) df = pd.DataFrame( data=[ [123, 68, "3M"], [189, 69, "4M"], [191, 71, np.nan], [np.nan, np.nan, np.nan], [np.nan, np.nan, np.nan], [np.nan, np.nan, np.nan], [234, 72, "3M"], [544, 68, "4M"] ], index=index, columns=["GDP", "Life expectancy", "Population"] ) # 核心填充逻辑 # 1. 按国家、日期排序,保证时序正确 df = df.sort_index(level=["country", "date"]) # 2. 按国家分组,连续执行前向、后向填充 filled_df = df.groupby(level="country").ffill().bfill()
填充效果校验
运行代码后得到的结果和预期完全匹配:
GDP Life expectancy Population country date BRA 1959-01-01 123.0 68.0 3M 1960-01-01 189.0 69.0 4M 1961-01-01 191.0 71.0 4M 1962-01-01 191.0 71.0 4M COL 1960-01-01 234.0 72.0 3M 1961-01-01 234.0 72.0 3M 1962-01-01 234.0 72.0 3M 1963-01-01 544.0 68.0 4M
关键注意点:填充顺序不能颠倒。如果先执行后向填充再执行前向填充,会把组内最后一个有效值之前的所有缺失都替换为最后一个值,违背“取距离缺失位置最近的可用值”的填充规则。
内容的提问来源于stack exchange,提问作者DataShytter
相关产品推荐
相关产品推荐

