棒球分析项目:抓取数据中字符串格式化以适配关键字参数需求
通用棒球球员姓名格式化解决方案
嘿,我之前爬体育数据的时候也遇到过这种乱序重复的姓名问题,太懂这种卡壳的感觉了!给你分享几个通用的处理方案,应该能覆盖所有球队的异常情况:
核心思路:针对重复拼接的异常特征处理
你遇到的异常姓名本质是抓取时重复提取了姓名的完整形式和缩写形式(比如Austin Riley+A. A.Riley),我们可以通过正则匹配、过滤缩写词这两种思路来快速校正。
方案1:正则匹配提取完整姓名(精准度高)
这种方法直接定位完整的「名+姓」组合,跳过后面的重复缩写部分,适配你提到的典型异常格式:
import re import pandas as pd def normalize_player_name(name): # 先清理多余空格 cleaned_name = re.sub(r'\s+', ' ', name.strip()) # 匹配「完整名+姓」的核心模式,跳过后续的重复内容 match_result = re.match(r'([A-Z][a-z]+ [A-Z][a-z]+)(.*)', cleaned_name) if match_result: return match_result.group(1) # 处理其他重复情况:比如名字/姓重复出现(如Freddie Freddie Freeman) name_parts = cleaned_name.split() unique_parts = [] seen = set() for part in name_parts: # 跳过带点的缩写(如A.) if '.' in part: continue if part not in seen: seen.add(part) unique_parts.append(part) # 返回去重后的拼接结果,避免空值 return ' '.join(unique_parts) if unique_parts else cleaned_name # 应用到你的DataFrame df['normalized_player_name'] = df['player_name'].apply(normalize_player_name)
方案2:过滤缩写词取核心姓名(更通用)
棒球球员姓名基本都是「名+姓」结构,很少有复杂中间名,我们可以直接过滤掉带点的缩写词,取前两个有效单词:
def normalize_player_name_v2(name): cleaned_name = re.sub(r'\s+', ' ', name.strip()) # 保留非缩写词,同时兼容Jr./III这类合法后缀 valid_parts = [ part for part in cleaned_name.split() if ('.' not in part) or part in ['Jr.', 'III', 'II'] ] # 取前两个单词(名+姓),不足的话返回所有有效部分 return ' '.join(valid_parts[:2]) if len(valid_parts)>=2 else ' '.join(valid_parts)
测试验证
用你的示例测试:
- 输入:
Austin RileyA. A.Riley→ 输出:Austin Riley - 输入:
Freddie FreemanF. F.Freeman→ 输出:Freddie Freeman - 输入:
Ozzie Albies→ 输出:Ozzie Albies(正常姓名不受影响)
额外优化建议
如果后续遇到带后缀的姓名(如Ken Griffey Jr.),可以在过滤逻辑里加入这些合法后缀的白名单;要是你的统计函数依赖标准姓名库,还可以把校正后的姓名和标准库做模糊匹配进一步校验,但上面的方案已经能覆盖绝大多数抓取到的异常情况了。
内容的提问来源于stack exchange,提问作者avawt
相关产品推荐
相关产品推荐

