如何合并多份FIFA球员DataFrame?处理非共现行数据
Hey there! Let's work through this problem together—since you're new to Pandas, this is a super common use case once you learn how to merge/shape data with specific keys instead of relying on indexes. Here's a step-by-step solution:
步骤1:给每个数据集添加年份标识
首先,每个DataFrame对应FIFA13到FIFA17,我们要给每个表加上Year列,这样后续能明确区分不同年份的数据:
# 假设你的5个DataFrame分别叫fifa13, fifa14, fifa15, fifa16, fifa17 fifa13['Year'] = 2013 fifa14['Year'] = 2014 fifa15['Year'] = 2015 fifa16['Year'] = 2016 fifa17['Year'] = 2017
步骤2:合并所有数据集到一个大表
用pd.concat把5个表合并成一个统一的DataFrame,这样后续处理会更高效:
import pandas as pd all_fifa_data = pd.concat([fifa13, fifa14, fifa15, fifa16, fifa17], ignore_index=True)
ignore_index=True会重置合并后的索引,避免出现重复索引的问题。
步骤3:重塑数据为「球员-年度评分」格式
现在我们要把数据转换成每位球员一行,每年的评分为一列的格式,未进入当年Top80的球员会自动填充NaN(也就是你需要的空值)。这里用pivot_table最稳妥(能处理偶尔出现的重复球员条目):
player_yearly_ratings = all_fifa_data.pivot_table( index='姓名', # 以球员姓名为行索引 columns='Year', # 以年份为列索引 values='Overall', # 要展示的评分数据 aggfunc='first' # 如果同一年有重复球员,取第一条数据 ) # 可选:把姓名从索引变回普通列,方便查看和后续操作 player_yearly_ratings = player_yearly_ratings.reset_index()
如果确定每个球员在同一年只会出现一次(Top80里不会有重复),也可以用更简洁的pivot:
player_yearly_ratings = all_fifa_data.pivot(index='姓名', columns='Year', values='Overall').reset_index()
为什么之前的join/merge没起作用?
你之前用join或merge时默认是基于索引合并,而不是姓名列。如果想用merge逐个合并,需要指定on='姓名'并使用outer join(保留所有球员,不管是否在当年Top80里),比如:
# 先初始化第一个年份的数据,重命名评分列 merged_df = fifa13[['姓名', 'Overall']].rename(columns={'Overall': '2013'}) # 逐个合并后续年份,用outer join保留所有球员 merged_df = merged_df.merge( fifa14[['姓名', 'Overall']].rename(columns={'Overall': '2014'}), on='姓名', how='outer' ) merged_df = merged_df.merge( fifa15[['姓名', 'Overall']].rename(columns={'Overall': '2015'}), on='姓名', how='outer' ) # 重复上述操作合并2016和2017的数据
不过这种方法比concat+pivot繁琐,更推荐用前者。
额外小贴士:处理同名球员
如果遇到同名不同球员的情况(比如两个叫"David Silva"的),可以把姓名和Club一起作为索引,避免混淆:
player_yearly_ratings = all_fifa_data.pivot_table( index=['姓名', 'Club'], columns='Year', values='Overall', aggfunc='first' ).reset_index()
这样处理后,像N. Vidić这类退役后没进入Top80的球员,后续年份的评分就会显示为NaN,完全符合你的需求!
内容的提问来源于stack exchange,提问作者pandasman

