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

如何基于另一Pandas DataFrame按规则补全Python中DataFrame的NaN值

问题描述

现有两个Pandas DataFrame:

df1 的定义与数据

import pandas as pd
import numpy as np

d1 = {'id': [1, 2, 3, 4], 'col1': [13, np.nan, 15, np.nan], 'col2': [23, np.nan, np.nan, np.nan]}
df1 = pd.DataFrame(data=d1)

df1 数据展示:

idcol1col2
113.023.0
2NaNNaN
315.0NaN
4NaNNaN

df2 的定义与数据

d2 = {'id': [2, 3, 4], 'col1': [14, 150, 16], 'col2': [24, 250, np.nan]}
df2 = pd.DataFrame(data=d2)

df2 数据展示:

idcol1col2
21424.0
3150250.0
416NaN

替换规则

需用df2的非NaN值替换df1的NaN字段,满足以下条件:

  • 两个DataFrame的id列值唯一,替换时需匹配相同id
  • 两个DataFrame行数不一定相同
  • 仅处理col1和col2列,其他列不受影响
  • 仅当df1对应行的col1/col2存在NaN,且df2同id行的col1和col2均为非NaN时,才用df2的整行替换df1该行;若df2对应行有任一NaN,则不替换df1该行

预期结果

处理后df1应如下:

idcol1col2
113.023.0
21424
3150.0250.0
4NaNNaN
解决方案

推荐两种简洁的Pandas实现方式,都能完美满足需求:

方法一:分步清晰版

# 1. 筛选df2中col1和col2均非空的行——只有这些行具备替换资格
valid_updates = df2.dropna(subset=["col1", "col2"])

# 2. 按id左连接df1与有效更新行,获取对应可替换的值
merged = df1.merge(valid_updates, on="id", how="left", suffixes=("", "_from_df2"))

# 3. 对col1和col2分别替换:优先用df2的有效值,无有效值则保留df1原数据
for col in ["col1", "col2"]:
    df1[col] = merged[f"{col}_from_df2"].combine_first(df1[col])

方法二:链式简洁版

如果追求代码更紧凑,可借助索引匹配实现:

# 筛选df2有效行并将id设为索引
valid_updates = df2.dropna(subset=["col1", "col2"]).set_index("id")

# 将df1设为id索引,用combine_first自动匹配替换,最后重置索引恢复结构
df1 = df1.set_index("id").combine_first(valid_updates).reset_index()

核心逻辑说明

  • dropna(subset=["col1", "col2"]):精准过滤掉df2中任一目标列有空值的行,确保只有完全有效的数据参与替换
  • combine_first:Pandas原生的缺失值替换方法,调用A.combine_first(B)时,会用B的非空值替换A的空值,A的非空值则保留,完全契合替换规则
  • 以id为匹配键(索引或merge关联键),保证只有同id的行才会触发替换,符合id唯一的要求

运行后得到的结果与预期完全一致:

id   col1   col2
0   1   13.0   23.0
1   2   14.0   24.0
2   3  150.0  250.0
3   4    NaN    NaN

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 07:44:16