如何仅将df_2的odds列值传递给df_1每组匹配的首行?
Pandas实现仅首行匹配赋值的解决方案
需求说明
现有两个Pandas DataFrame:
df_1包含date、team1、team2、odds列,初始odds为空字符串df_2包含runner_home、runner_away、odds列,存储球队组合对应的赔率
核心要求:当df_1中的team1/team2与df_2的runner_home/runner_away完全匹配时,将df_2的odds值填入df_1对应行;同一球队组合在df_1中出现多次时,仅为第一次出现的行赋值,其余行保持原odds值。
示例数据
import pandas as pd df_1 = pd.DataFrame({ 'date':['2023-04-25', '2023-04-25', '2024-06-15', '2023-04-25', '2024-10-02'], 'team1':['Chelsea', 'Barcelona', 'Vasco', 'Barcelona', 'Vasco'], 'team2':['Liverpool', 'Real Madrid', 'Flamengo', 'Real Madrid', 'Flamengo'], 'odds':['', '', '', '', ''] }) df_2 = pd.DataFrame({ 'runner_home':['Barcelona', 'Vasco'], 'runner_away':['Real Madrid', 'Flamengo'], 'odds':[2.50, 1.50] })
期望结果
df_1 = pd.DataFrame({ 'date':['2023-04-25', '2023-04-25', '2024-06-15', '2023-04-25', '2024-10-02'], 'team1':['Chelsea', 'Barcelona', 'Vasco', 'Barcelona', 'Vasco'], 'team2':['Liverpool', 'Real Madrid', 'Flamengo', 'Real Madrid', 'Flamengo'], 'odds':['', 2.50, 1.50, '', ''] })
解决方案
直接使用merge会给所有匹配行赋值,我们可以通过标记首次出现的匹配行来实现需求,以下是两种可行方案:
方案1:合并+条件赋值
import pandas as pd # 标记每个球队组合的首次出现行(首次出现为False,重复行标记为True) df_1['is_duplicate'] = df_1.duplicated(subset=['team1', 'team2'], keep='first') # 左连接两个DataFrame,获取匹配的赔率值 merged = df_1.merge( df_2, left_on=['team1', 'team2'], right_on=['runner_home', 'runner_away'], how='left', suffixes=('', '_new') ) # 仅给首次出现的匹配行赋值,其余行保持原odds df_1['odds'] = merged.apply( lambda row: row['odds_new'] if not row['is_duplicate'] and pd.notna(row['odds_new']) else row['odds'], axis=1 ) # 清理临时列 df_1.drop('is_duplicate', axis=1, inplace=True) print(df_1)
方案2:字典映射+批量赋值(高效版)
适合数据量较大的场景,避免使用apply提升运行效率:
import pandas as pd # 标记每个球队组合的首次出现行 first_occurrence = ~df_1.duplicated(subset=['team1', 'team2'], keep='first') # 构建球队组合到赔率的映射字典 odds_map = df_2.set_index(['runner_home', 'runner_away'])['odds'].to_dict() # 仅给首次出现的匹配行赋值 df_1.loc[first_occurrence, 'odds'] = df_1.loc[first_occurrence].apply( lambda x: odds_map.get((x['team1'], x['team2']), x['odds']), axis=1 ) print(df_1)
两种方案运行后输出结果均与期望一致:
date team1 team2 odds 0 2023-04-25 Chelsea Liverpool 1 2023-04-25 Barcelona Real Madrid 2.5 2 2024-06-15 Vasco Flamengo 1.5 3 2023-04-25 Barcelona Real Madrid 4 2024-10-02 Vasco Flamengo
内容的提问来源于stack exchange,提问作者Digital Farmer
相关产品推荐
相关产品推荐

