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

如何按动态规则填充DataFrame中的NaN值?

解决动态规则的DataFrame NaN填充问题

需求说明

给定包含数值和NaN的DataFrame,需按照以下规则填充:

  • 找到每个非NaN值,若其后续存在连续NaN,将该非NaN值与后续所有连续NaN替换为「原值/(连续NaN数量+1)」
  • 示例:第3行(值24)和第4行(NaN)替换为12(24/2);第6行(值15)、7、8行(NaN)替换为5(15/3)

示例DataFrame

import pandas as pd
import numpy as np

df = pd.DataFrame(
    {'Column 1': [10, 12, 24, np.nan, 20, 15, np.nan, np.nan, 2]},
    index=range(1, 10)
)

解决方案

方法一:基于分组标识的高效处理

利用cumsum()生成分组ID,将每个「非NaN+连续NaN」序列划分为同一组,再批量填充:

# 生成分组ID:每个连续的非NaN+NaN序列分配唯一ID
df['group_id'] = df['Column 1'].notna().cumsum()

# 遍历每个分组处理
for gid, group in df.groupby('group_id'):
    # 仅处理包含NaN的分组(长度>1)
    if len(group) > 1:
        original_value = group['Column 1'].iloc[0]
        fill_value = original_value / len(group)
        df.loc[group.index, 'Column 1'] = fill_value

# 删除临时分组列
df.drop('group_id', axis=1, inplace=True)

方法二:逐行遍历定位分组(适合小数据量)

手动定位每个需要处理的组的起始和结束位置,再填充:

# 标记非NaN且下一行是NaN的行(即分组起始行)
mask = df['Column 1'].notna() & df['Column 1'].shift(-1).isna()
start_indices = df[mask].index

# 遍历每个起始行处理
for idx in start_indices:
    current_idx = idx + 1
    # 找到连续NaN的最后一行
    while current_idx in df.index and pd.isna(df.loc[current_idx, 'Column 1']):
        current_idx += 1
    end_idx = current_idx - 1
    group_size = end_idx - idx + 1
    fill_value = df.loc[idx, 'Column 1'] / group_size
    # 填充整个组
    df.loc[idx:end_idx, 'Column 1'] = fill_value

处理结果

执行上述代码后,DataFrame变为:

Column 1
1      10.0
2      12.0
3      12.0
4      12.0
5      20.0
6       5.0
7       5.0
8       5.0
9       2.0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 16:05:38