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

Pandas如何按规则填充日期区间内的空值?

问题描述

现有如下DataFrame:

dateidvalue1value2
2022-01-0111112
2022-01-0211213
2022-01-0311NaNNaN
2022-01-0411NaNNaN
2022-01-0511515
2022-01-0122113
2022-01-0222NaNNaN
2022-01-0322NaNNaN
2022-01-0422NaNNaN
2022-01-05221234
2022-01-013324
2022-01-023348
2022-01-0333NaNNaN
2022-01-0433NaNNaN
2022-01-0533NaNNaN
2022-01-0144NaNNaN
2022-01-02443489
2022-01-0344NaNNaN
2022-01-044435NaN
2022-01-0544NaNNaN

需要满足以下处理要求:

  • 按id列分组
  • 仅当整行为空时填充空值(NaN)
  • 仅当分组后存在后续有值的日期时才填充空值:比如id=11的2022-01-03、04因为后续05有有效值,所以填充;id=33的后续无有效值,所以不填充

尝试用ffill()无法满足第3点要求,求解决方案。

解决方案

可以通过以下步骤实现需求:

  1. 标记整行空值的行:判断每行的value1、value2是否全为NaN,生成辅助列标记这类行
  2. 标记分组内后续是否有有效值:对每个分组从后往前判断,标记当前行之后是否存在非整行空值的记录
  3. 条件式前向填充:先做分组前向填充,再仅对符合条件的行替换填充值

具体代码实现:

import pandas as pd
import numpy as np

# 构建原始DataFrame
df = pd.DataFrame({
    'date': ['2022-01-01', '2022-01-02', '2022-01-03', '2022-01-04', '2022-01-05',
             '2022-01-01', '2022-01-02', '2022-01-03', '2022-01-04', '2022-01-05',
             '2022-01-01', '2022-01-02', '2022-01-03', '2022-01-04', '2022-01-05',
             '2022-01-01', '2022-01-02', '2022-01-03', '2022-01-04', '2022-01-05'],
    'id': [11,11,11,11,11,22,22,22,22,22,33,33,33,33,33,44,44,44,44,44],
    'value1': [1,2,np.nan,np.nan,5,11,np.nan,np.nan,np.nan,12,2,4,np.nan,np.nan,np.nan,np.nan,34,np.nan,35,np.nan],
    'value2': [12,13,np.nan,np.nan,15,3,np.nan,np.nan,np.nan,34,4,8,np.nan,np.nan,np.nan,np.nan,89,np.nan,np.nan,np.nan]
})

# 步骤1:标记整行空值的行
df['is_full_nan'] = df[['value1', 'value2']].isna().all(axis=1)

# 步骤2:标记分组内当前行之后是否有非空行
def mark_future_valid(group):
    # 从后往前累积判断,只要后续有非全空行则标记为True
    group['has_future'] = (~group['is_full_nan'])[::-1].cumsum().astype(bool)[::-1]
    return group

df = df.groupby('id').apply(mark_future_valid).reset_index(drop=True)

# 步骤3:生成填充后的数据,仅替换符合条件的行
filled_values = df.groupby('id')[['value1', 'value2']].ffill()
df[['value1', 'value2']] = np.where(
    df[['is_full_nan', 'has_future']].all(axis=1),
    filled_values,
    df[['value1', 'value2']]
)

# 移除辅助列
df = df.drop(['is_full_nan', 'has_future'], axis=1)

print(df)

代码说明:

  • is_full_nan列:精准筛选出需要处理的整行空值行,避免误填充部分空值的行
  • has_future列:通过从后往前的累积判断,确保只填充那些后续还有有效值的空行,解决ffill()会填充到分组末尾的问题
  • 条件替换:仅将“整行空+后续有有效值”的行替换为前向填充结果,其余行保留原始数据,完全匹配需求

执行后得到的结果与期望输出一致。

内容的提问来源于stack exchange,提问作者twagh24

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 09:54:53