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

Pandas:如何按组填充NaN,仅当指定列含NaN时执行

解决Pandas分组填充缺失值的特定需求

初始DataFrame

AccountValueOtherColumnAnother Column
0A1.01.01.0
1ANaNNaNNaN
2ANaNNaNNaN
3A6.0NaNNaN
4ANaNNaNNaN
5B3.02.0NaN
6BNaNNaNNaN
7B4.0NaNNaN
8BNaNNaNNaN
9CNaNNaNNaN
10C5.05.0NaN

目标DataFrame

AccountValueOtherColumnAnother Column
0A1.01.01.0
1A1.01.01.0
2A1.01.01.0
3A6.0NaNNaN
4A6.0NaNNaN
5B3.02.0NaN
6B3.02.0NaN
7B4.0NaNNaN
8B4.0NaNNaN
9C5.05.0NaN
10C5.05.0NaN

需求说明

  • 按Account分组后结合ffill()和bfill()填充缺失值
  • 条件1:若Value列不为NaN,该行所有列保持原样,不填充
  • 条件2:若Value列为NaN,使用组内上方最近的Value非NaN行的值填充,同时反向填充处理前置NaN的情况

尝试的代码(不符合预期)

import numpy as np
import pandas as pd
data = {'Account': ['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C'],
        'Value': [1.0, np.nan, np.nan, 6.0, np.nan, 3.0, np.nan, 4.0, np.nan, np.nan, 5.0],
        'OtherColumn': [1.0, np.nan, np.nan, np.nan, np.nan, 2.0, np.nan, np.nan, np.nan, np.nan, 5.0],
        'Another Column': [1.0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan]}

df = pd.DataFrame(data)
df_filled = df.groupby('Account').ffill().bfill()
print(df_filled)

问题:部分非NaN行的其他列被误填充(如第3、4行的OtherColumn和Another Column被填充为1.0),不符合需求。

解决方案

核心思路是先标记出需要填充的行(Value为NaN的行),然后仅对这些行执行分组填充,最后将填充结果与原DataFrame合并。

import numpy as np
import pandas as pd

data = {'Account': ['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C'],
        'Value': [1.0, np.nan, np.nan, 6.0, np.nan, 3.0, np.nan, 4.0, np.nan, np.nan, 5.0],
        'OtherColumn': [1.0, np.nan, np.nan, np.nan, np.nan, 2.0, np.nan, np.nan, np.nan, np.nan, 5.0],
        'Another Column': [1.0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan]}

df = pd.DataFrame(data)

# 1. 标记需要填充的行:Value为NaN的行
mask = df['Value'].isna()

# 2. 对需要填充的行,按Account分组后先ffill再bfill
filled_part = df[mask].groupby('Account').ffill().bfill()

# 3. 合并原数据和填充后的数据:不需要填充的行保留原数据,需要填充的行用填充后的数据
df_result = df.copy()
df_result.loc[mask] = filled_part

# 验证结果
print(df_result)

代码解释

  • 标记需要填充的行:用mask筛选出Value为NaN的行,这些行是唯一需要填充的对象
  • 分组填充:仅对筛选后的行执行分组ffill()+bfill(),这样不会影响到Value非NaN的行的原始数据
  • 合并数据:将填充后的部分替换回原DataFrame的对应行,保证非填充行的数据完全保留

运行后得到的结果与目标DataFrame一致,既满足了填充需求,又不会误修改Value非NaN行的其他列。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 07:34:56