如何关联足球比赛与球员统计DataFrame,生成每位球员特征列
问题分析与解决方案
核心问题
你的代码生成空DataFrame主要有三个关键问题:
- 未填充结果字典:
joined_dfs字典始终为空,后续pd.concat自然没有可拼接的数据。 - 关联键不匹配:你用
player_name作为关联字段,但test_matches_df中的home_player_1等字段存储的是球员ID(从示例值111111的格式判断),而非球员名称,导致关联后无匹配结果。 - 错误的赋值语法:
[alias] = pd.merge(...)是错误写法,merge返回的是DataFrame,不能用列表解构赋值。
修正后的代码
基于数据结构判断,test_matches_df的球员列对应players_stats的player_api_id字段,以下是修正后的实现:
import pandas as pd # 定义所有需要关联的球员列 player_columns = ['home_player_1', 'home_player_2', 'home_player_3', 'home_player_4', 'home_player_5', 'home_player_6', 'home_player_7', 'home_player_8', 'home_player_9', 'home_player_10', 'home_player_11', 'away_player_1', 'away_player_2', 'away_player_3', 'away_player_4', 'away_player_5', 'away_player_6', 'away_player_7', 'away_player_8', 'away_player_9', 'away_player_10', 'away_player_11'] # 统一关联键类型:将比赛数据中的球员ID转为int,匹配球员统计数据的player_api_id类型 test_matches_df[player_columns] = test_matches_df[player_columns].astype(int) # 初始化结果为原始比赛数据的副本 result_df = test_matches_df.copy() # 循环处理每个球员列,合并对应的统计特征 for player_col in player_columns: # 重命名球员统计列,添加前缀区分不同球员 renamed_stats = players_stats.rename(columns={ col: f"{player_col}_{col}" for col in players_stats.columns if col != 'player_api_id' }) # 左连接,保留所有比赛数据,匹配对应球员的统计特征 merged_df = pd.merge( result_df, renamed_stats, left_on=player_col, right_on='player_api_id', how='left' ) # 丢弃重复的player_api_id列,更新结果DataFrame result_df = merged_df.drop(columns=['player_api_id']) # 查看最终结果 print(result_df.head())
关键说明
- 类型统一:确保关联键类型一致,避免因字符串与数字类型不匹配导致的关联失败。
- 列名自动生成:通过字典推导式将球员统计列重命名为
home_player_1_strength、away_player_5_acceleration这类符合需求的格式。 - 逐步合并:每次合并后更新结果,既保留原始比赛数据,又逐步添加所有球员的统计特征。
额外排查建议
如果合并后仍有大量空值,可进行以下验证:
- 检查比赛数据中的球员ID是否存在于球员统计数据中:
# 提取所有比赛中的球员ID all_match_player_ids = pd.concat([test_matches_df[col] for col in player_columns]) # 找出在统计数据中不存在的ID missing_ids = all_match_player_ids[~all_match_player_ids.isin(players_stats['player_api_id'])] print(f"无对应统计数据的球员ID数量:{len(missing_ids.unique())}") - 清理球员统计数据中的重复ID:
# 保留每个球员ID的最新记录 players_stats = players_stats.drop_duplicates(subset='player_api_id', keep='last')
内容的提问来源于stack exchange,提问作者spool
相关产品推荐
相关产品推荐

