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

Pandas Merge:优雅处理合并时列值保留与空值填充的方案

合并DataFrame时优先保留主表列值,仅填充空值

现有两个DataFrame结构如下:

df1[['name', 'year', 'col1', 'col2', 'col3']]
df2[['name', 'year', 'col2', 'col3', 'col4']]

需求:按name和year合并df1与df2,优先保留df1中col2、col3的所有值,仅当df1对应位置为None(即NaN)时,才用df2中的对应值填充。

传统做法是合并后用ffill()再删除重复列,但多次同类合并会导致代码冗余,想了解pd.merge是否有内置选项直接实现这个需求。


示例数据

df1

name  year  col1  col2  col3
0    a  2000     1  0.00  1.00
1    a  2001     2  2.00  3.00
2    b  2002     3  4.00  5.00
3    b  2003     4  6.00  7.00
4    c  2004     5  8.00   NaN
5    c  2005     6   NaN  9.00

df2

name  year  col2   col3  col4
0    b  2003 10.00 100.00     5
1    b  2004 20.00 300.00     6
2    c  2004 30.00 500.00     7
3    c  2005   NaN 700.00     8
4    d  2006 50.00    NaN     9
5    d  2007 60.00 900.00    10

解决方案

pd.merge本身没有直接实现该逻辑的内置参数,但可以通过合并后用combine_first填充重叠列的方式,替代繁琐的ffill和删列操作,代码更简洁且可复用。

实现代码

import pandas as pd

# 初始化示例数据
df1 = pd.DataFrame({'name': ['a', 'a', 'b', 'b', 'c', 'c'],
                    'year': [2000, 2001, 2002, 2003, 2004, 2005],
                    'col1': [1,2,3,4,5,6],
                    'col2': [0,2,4,6,8,None],
                    'col3': [1,3,5,7,None,9]})

df2 = pd.DataFrame({'name': ['b', 'b', 'c', 'c', 'd', 'd'],
                    'year': [2003, 2004, 2004, 2005, 2006, 2007],
                    'col2': [10,20,30,None,50,60],
                    'col3': [100,300,500,700,None,900],
                    'col4': [5,6,7,8,9,10]})

# 1. 按name和year外合并,给重叠列加后缀区分
merged = pd.merge(df1, df2, on=['name', 'year'], how='outer', suffixes=('_df1', '_df2'))

# 2. 对col2、col3优先保留df1的值,空值用df2填充
for col in ['col2', 'col3']:
    merged[col] = merged[f'{col}_df1'].combine_first(merged[f'{col}_df2'])

# 3. 删除临时后缀列,整理最终列顺序
final_df = merged.drop(columns=['col2_df1', 'col2_df2', 'col3_df1', 'col3_df2'])[['name', 'year', 'col1', 'col2', 'col3', 'col4']]

print(final_df)

运行结果

name  year  col1  col2   col3  col4
0    a  2000   1.0   0.0    1.0   NaN
1    a  2001   2.0   2.0    3.0   NaN
2    b  2002   3.0   4.0    5.0   NaN
3    b  2003   4.0   6.0    7.0   5.0
4    b  2004   NaN  20.0  300.0   6.0
5    c  2004   5.0   8.0  500.0   7.0
6    c  2005   6.0   NaN    9.0   8.0
7    d  2006   NaN  50.0    NaN   9.0
8    d  2007   NaN  60.0  900.0  10.0

逻辑说明

  1. 外合并:用how='outer'确保保留两个表的所有行,suffixes给重叠列加后缀避免列名冲突。
  2. 优先填充:combine_first会自动用右侧列的值填充左侧列的空值,完全匹配"保留df1值、仅空值用df2填充"的需求。
  3. 代码复用:可以把逻辑封装成函数,多次合并时直接调用:
def merge_with_priority(main_df, other_df, on_cols, priority_cols):
    merged = pd.merge(main_df, other_df, on=on_cols, how='outer', suffixes=('_main', '_other'))
    for col in priority_cols:
        merged[col] = merged[f'{col}_main'].combine_first(merged[f'{col}_other'])
    drop_cols = [f'{col}_main' for col in priority_cols] + [f'{col}_other' for col in priority_cols]
    final_cols = on_cols + [col for col in main_df.columns if col not in on_cols] + [col for col in other_df.columns if col not in on_cols + priority_cols]
    return merged.drop(columns=drop_cols)[final_cols]

# 调用示例
final_df = merge_with_priority(df1, df2, on_cols=['name', 'year'], priority_cols=['col2', 'col3'])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 00:24:50