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

合并匹配含球员姓名的Pandas DataFrame:解决merge结果为空问题

Pandas球员数据合并为空问题解决方法

问题背景

现有两个Pandas DataFrame:

  • df1:包含「Player(球员姓名)」和「Rating」列
  • df2:包含「Player」及「Team」「Age」「Value」等多列

需求是将df1的Rating数据合并到df2中,保留df2全部字段。尝试带正则替换的merge代码后,合并结果为空,需排查解决。

数据示例

df1数据:

PlayerRating
O. Fuglsang53
J. Jensen-Abbew53
M. Enggård53
J. Liburd53

df2数据:

PlayerTeamAgeValue
R. Mudražijaa1a2a3
J. Gomezb1b2b3
T. Mølgaardc1c2c2
J. Liburdd1d2d3

尝试的错误代码

dfmerged = df1.merge(df2,
          left_on=df1['Player'].str.replace(r'^(.)\w+', r'\1.', regex=True),
          right_on='Player'
         )

问题分析

你写的正则表达式r'^(.)\w+'逻辑错误:

  • ^(\.)匹配字符串第一个字符,\w+匹配后续字母/数字,但\w不匹配点号(.),所以对于df1中O. Fuglsang这类带点的名字,正则只能匹配到O,替换后结果还是O.,和df2的Player字段完全无法匹配,导致合并结果为空。

正确解决步骤

步骤1:基础左合并(优先匹配一致姓名)

先直接用how='left'执行左合并,保留df2所有行,自动匹配格式完全一致的球员:

df_merged = df2.merge(df1, on='Player', how='left')

这一步会先搞定大部分格式一致的球员,未匹配到的Rating会显示为NaN。

步骤2:排查未匹配的球员

找出df2中未匹配的球员,分析格式差异:

# 提取df2中未匹配Rating的球员姓名
unmatched_players = df_merged[df_merged['Rating'].isna()]['Player'].tolist()
print("未匹配的球员:", unmatched_players)
print("df1中的姓名样本:", df1['Player'].sample(5).tolist())

通过对比可以发现具体格式差异(比如首字母位置、大小写、特殊字符、缩写方式等)。

步骤3:针对性处理格式差异

场景1:姓名缩写顺序不同

如果df1是「首字母. 姓氏」格式,df2是「姓氏, 首字母.」格式,可生成统一匹配键合并:

# 给df1生成匹配键:首字母_姓氏
df1['match_key'] = df1['Player'].str.split('. ', expand=True)[0] + '_' + df1['Player'].str.split('. ', expand=True)[1]

# 给df2生成匹配键:首字母_姓氏
df2['match_key'] = df2['Player'].str.split(', ', expand=True)[1].str.replace('.', '') + '_' + df2['Player'].str.split(', ', expand=True)[0]

# 用匹配键合并,保留df2全部字段
df_merged = df2.merge(df1, on='match_key', how='left')
# 清理临时列,重命名字段
df_merged = df_merged[['Player_x', 'Team', 'Age', 'Value', 'Rating']].rename(columns={'Player_x': 'Player'})

场景2:特殊字符差异(如å/a、ø/o)

统一转换为普通字符后再匹配:

import unicodedata

def normalize_name(name):
    # 去除特殊字符并转小写
    return unicodedata.normalize('NFKD', name).encode('ascii', 'ignore').decode('utf-8').lower()

# 生成标准化匹配键
df1['match_key'] = df1['Player'].apply(normalize_name)
df2['match_key'] = df2['Player'].apply(normalize_name)

# 合并并清理临时列
df_merged = df2.merge(df1, on='match_key', how='left')
df_merged = df_merged[['Player_x', 'Team', 'Age', 'Value', 'Rating']].rename(columns={'Player_x': 'Player'})

总结

  1. 先通过基础左合并解决大部分匹配需求;
  2. 针对少数格式差异的球员,先排查差异类型,再生成统一匹配键进行合并;
  3. 避免盲目使用不熟悉的正则,优先从数据样本入手分析格式规律。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 05:01:09