Pandas多列一对多合并时实现首次匹配填充值的方法
Pandas多列一对多合并时实现首次匹配填充值的方法
我懂你现在的困扰——用普通的左连接做多列一对多合并时,同组的每一行都会重复填充匹配到的value,但你只希望每组的第一行显示对应值,后面的留空或者NaN对吧?其实只需要在常规合并后加一步分组去重的处理就能搞定,我给你一步步拆解实现:
第一步:先准备示例数据
先把你给出的两个DataFrame还原出来,方便后续操作:
import pandas as pd df1 = pd.DataFrame({ 'date':['2025-03-01','2025-03-01', '2025-03-02'], 'period':[1,1,2], 'company':['aa','aa','b'] }) df2 = pd.DataFrame({ 'date':['2025-03-01', '2025-03-02'], 'period':[1,2], 'company':['aa','b'], 'value':[4,8] })
第二步:常规左连接+分组去重填充
先做普通的左连接拿到基础合并结果,再对分组后的value列做处理,只保留每组第一个匹配的值:
# 1. 执行常规左连接,确保df1的所有行都被保留 merged = df1.merge(df2, on=['date', 'period', 'company'], how='left') # 2. 按合并的分组键分组,将每组除第一行外的value替换为NaN merged['value'] = merged.groupby(['date', 'period', 'company'])['value'].mask(lambda x: x.duplicated(keep='first'))
运行后打印结果,就是你想要的效果:
date period company value 0 2025-03-01 1 aa 4.0 1 2025-03-01 1 aa NaN 2 2025-03-02 2 b 8.0
额外需求:如果想要空字符串而非NaN
如果你希望重复行的value显示为空字符串(而不是默认的NaN),只需要把第二步的代码改成:
merged['value'] = merged.groupby(['date', 'period', 'company'])['value'].mask(lambda x: x.duplicated(keep='first'), '')
这样输出的第二行value就会是空字符串啦。
逻辑解释
- 左连接的作用是确保所有
df1的行都被保留,并且拿到df2中对应的value值; groupby配合mask和duplicated是核心:duplicated(keep='first')会把每组中除第一个元素外的所有重复项标记为True,mask则会把这些标记为True的位置的value替换成你指定的内容(默认NaN,或者空字符串),完美实现“仅首次匹配填充值”的需求。
内容来源于stack exchange
相关产品推荐
相关产品推荐

