如何在Pandas DataFrame中仅填充两有效值之间的NaN空缺?
仅填充Pandas DataFrame中两个有效值之间的NaN(向前填充)
在二手车定价数据项目中,现有Pandas DataFrame存在数据空缺,需要仅对位于两个有效值之间的NaN进行向前填充。常规的.ffil()、.bfill()、.fillna()方法仅支持单向全局填充,无法满足该需求。
示例代码
import pandas as pd from datetime import datetime import numpy as np date_index = pd.date_range(datetime(2023,2,1), datetime(2023,2,8)) prices_dict = { 'car1': [1000, 1000, np.nan, np.nan, 1200, 1250, np.nan, np.nan], 'car2': [np.nan, np.nan, np.nan, 500, 600, 610, 630, np.nan], 'car3': [np.nan, 1000, np.nan, 950, np.nan, 950, np.nan, np.nan], 'car4': [np.nan, 790, np.nan, np.nan, np.nan, 800, 750, 750], } prices_df = pd.DataFrame(data=prices_dict, index=date_index)
原始数据
-------- car1 car2 car3 car4 2023-02-01 1000.0 2023-02-02 1000.0 1000.0 790.0 2023-02-03 2023-02-04 500.0 950.0 2023-02-05 1200.0 600.0 2023-02-06 1250.0 610.0 950.0 800.0 2023-02-07 630.0 750.0 2023-02-08 750.0
预期填充结果
-------- car1 car2 car3 car4 2023-02-01 1000.0 2023-02-02 1000.0 1000.0 790.0 2023-02-03 1000.0 1000.0 790.0 2023-02-04 1000.0 500.0 950.0 790.0 2023-02-05 1200.0 600.0 950.0 790.0 2023-02-06 1250.0 610.0 950.0 800.0 2023-02-07 630.0 750.0 2023-02-08 750.0
解决方案
核心思路是:针对每一列,先确定有效值的覆盖区间(第一个非NaN值到最后一个非NaN值的范围),仅在该区间内执行向前填充,区间外的NaN保持不变。
实现代码
def fill_between_valid(df): filled_df = df.copy() for col in filled_df.columns: # 获取当前列所有非NaN值的索引 non_na_indices = filled_df[col].dropna().index # 若有效数值少于2个,无需填充 if len(non_na_indices) < 2: continue # 定义有效填充区间:从第一个有效值到最后一个有效值 start_idx = non_na_indices[0] end_idx = non_na_indices[-1] # 在区间内执行向前填充 filled_df.loc[start_idx:end_idx, col] = filled_df.loc[start_idx:end_idx, col].ffill() return filled_df # 应用函数 filled_prices = fill_between_valid(prices_df) print(filled_prices)
说明
- 遍历每一列,先判断是否存在至少两个有效值(只有一个或没有有效值时,无需填充中间NaN)
- 通过
dropna().index获取非NaN值的索引,确定填充的起止范围 - 仅在起止范围内使用
.ffill()向前填充,确保区间外的NaN保留原始状态
内容的提问来源于stack exchange,提问作者dg141
相关产品推荐
相关产品推荐

