MLB球员薪资建模:合并DataFrame后重复观测处理问题
MLB球员薪资与击球数据合并解决方案
问题根源
- 仅按
Name合并会触发笛卡尔积:同一球员同一年的多条薪资记录和多条击球数据交叉匹配,导致观测数暴增。 validate="1:1"报错是因为experiment或batting中,(Name, yearID)/(Name, Season)组合不唯一(比如球员一年内换队,薪资/击球数据按球队拆分)。
解决步骤
1. 清理数据集,确保合并键唯一
清理薪资数据集(experiment)
按playerID+yearID分组(playerID比Name更精准,避免同名球员混淆),处理同一年多薪资记录(比如取均值/总和):
# 聚合同球员同年的薪资数据 experiment_clean = experiment.groupby(['playerID', 'yearID', 'Name'])['salary'].mean().reset_index()
清理击球数据集(batting)
按Name+Season(或playerID+Season,如果batting含playerID)分组,合并同一年的击球数据:
# 聚合同球员同年的击球数据,按需选择聚合方式 batting_clean = batting.groupby(['Name', 'Season']).agg( H=('H', 'sum'), # 安打数取总和 HR=('HR', 'sum'), # 本垒打数取总和 AVG=('AVG', 'mean'), # 打击率取均值 # 其他击球字段按需添加 ).reset_index()
2. 精准合并数据集
如果batting包含playerID,优先用playerID+年份合并(彻底避免同名问题):
full_dataset = experiment_clean.merge( batting_clean, left_on=['playerID', 'yearID'], right_on=['playerID', 'Season'], how='inner' # 根据需求选择inner/left/right )
如果batting没有playerID,用Name+年份合并:
full_dataset = experiment_clean.merge( batting_clean, left_on=['Name', 'yearID'], right_on=['Name', 'Season'], how='inner' )
额外提示
- 永远优先用
playerID作为关联键,MLB数据中存在大量同名球员(比如Mike Jones),用Name合并会导致数据污染。 - 合并前可以用
duplicated()检查重复的合并键:# 检查experiment是否有重复的playerID+yearID print(experiment.duplicated(['playerID', 'yearID']).any()) # 检查batting是否有重复的Name+Season print(batting.duplicated(['Name', 'Season']).any())
内容的提问来源于stack exchange,提问作者Evan Maurer
相关产品推荐
相关产品推荐

