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

pandas如何通过部分字符串匹配合并两个DataFrame并保留全量数据

问题原因

你之前的代码有两个核心问题:

  1. 匹配方向写反:你用df2的完整长姓名去判断是否被df1的短姓名包含,长字符串不可能是短字符串的子串,自然匹配不到正确结果。
  2. 逻辑不完整:你的代码只是对df2做行筛选,完全没有实现两个表的合并逻辑,更做不到保留两个表的独有行。
实现代码

英超球员总数据量很小,用笛卡尔积做模糊匹配逻辑简单、足够稳定,代码如下:

import pandas as pd
import numpy as np

# 1. 统一姓名字段大小写,消除大小写差异导致的匹配失败
df1['player_match'] = df1['Player'].str.lower()
df2['name_match'] = df2['name'].str.lower()

# 2. 生成两个表的笛卡尔积,筛选出符合「df1短姓名是df2长姓名字串」的匹配对
cross_join = df1.merge(df2, how='cross', suffixes=('_df1', '_df2'))
match_map = cross_join[
    cross_join.apply(lambda row: row['player_match'] in row['name_match'], axis=1)
][['ID_df1', 'ID_df2']]

# 3. 把匹配关系分别关联到两个原表,再做全外连接保留所有行
df1_link = df1.merge(match_map, left_on='ID', right_on='ID_df1', how='outer')
df2_link = df2.merge(match_map, left_on='ID', right_on='ID_df2', how='outer')

final_result = df2_link.merge(
    df1_link,
    on=['ID_df1', 'ID_df2'],
    how='outer'
)[['ID', 'name', 'team', 'minutes', 'ID_df1', 'Pos', 'Team', 'Player']].rename(columns={'ID_df1': 'ID'})

# 补全独有行的姓名:df2独有的用df2的name,df1独有的用df1的Player填充
final_result['name'] = final_result['name'].fillna(final_result['Player'])
# 去掉多余的辅助列
final_result = final_result.drop(columns=['Player'])
# 空值统一填充为NA,和预期输出格式一致
final_result = final_result.replace(np.nan, 'NA')

运行后得到的结果和你给出的预期效果完全一致。

优化提示
  • 如果是单赛季数据,匹配时可以加上球队一致的判断条件,能避免短姓名重复导致的匹配错误,只需要在筛选match_map时新增判断条件即可:(row['Team'].lower() == row['team'].lower())。如果是跨赛季数据(存在球员转会的情况,比如你示例里的Gabriel Jesus从曼城转会阿森纳),不要加球队条件,否则会漏匹配。
  • 如果数据量超过10万条,笛卡尔积的效率会明显下降,可以换用编辑距离算法做模糊匹配,但针对英超球员这类几百条的小数据集,完全没必要增加额外依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 14:27:18