Python/Pandas基于公共列合并6个DataFrame值匹配错误的解决方法
你使用的outer合并语法本身不存在逻辑错误,国家与数值错配均由关联键不规范、原表数据或列名冲突导致,按以下步骤排查修复即可:
核心错配原因
- 不同DataFrame的
Country列取值不统一:同一国家存在简称/全称差异、前后多余空格、大小写不一致、特殊字符编码乱码等问题,导致本应匹配的行未正确关联,甚至和名称近似的其他国家错误匹配 - 单表内
Country列存在重复值:合并时触发多对多匹配生成笛卡尔积,直接造成行数据错位 - 非关联列重名无标识:多个表存在除
Country外的同名字段(如Score/Year/Index等通用列名),合并后自动生成的_x/_y后缀未被识别,易被误判为数值错配
分步修复方案
1. 统一清洗所有表的关联键
先对所有待合并表的Country列做标准化处理,消除格式差异:
import pandas as pd from functools import reduce data_frames = [WorldPopulation_df, WorldEconomy_df, WorldEducation_df, WorldAggression_df, WorldCorruption_df, WorldCyberCapabilities_df] cleaned_dfs = [] # 自定义国家名映射表,根据你实际排查到的同国异名补全即可 country_alias_map = { 'Us': 'United States', 'Usa': 'United States', 'United States Of America': 'United States', 'Uk': 'United Kingdom', 'England': 'United Kingdom', 'Russia': 'Russian Federation', 'South Korea': 'Korea, Rep.' # 其余差异名称按实际数据补充 } for df in data_frames: # 统一转字符串、去首尾空格、统一首字母大写格式 df['Country'] = df['Country'].astype(str).str.strip().str.title() # 替换别名 df['Country'] = df['Country'].replace(country_alias_map) cleaned_dfs.append(df)
2. 排查处理单表内的重复国家值
逐表检查Country列的重复项,避免多对多匹配导致的错位:
for idx, df in enumerate(cleaned_dfs): dup_count = df['Country'].duplicated().sum() if dup_count > 0: print(f"第{idx+1}个DataFrame存在{dup_count}条重复国家记录:") print(df[df['Country'].duplicated(keep=False)]['Country'].unique()) # 按业务规则去重,示例为数值列取均值、文本列取第一条,可根据需求修改聚合逻辑 num_cols = df.select_dtypes(include='number').columns.tolist() str_cols = [col for col in df.columns if col not in num_cols and col != 'Country'] agg_rule = {col: 'mean' for col in num_cols} agg_rule.update({col: 'first' for col in str_cols}) cleaned_dfs[idx] = df.groupby('Country', as_index=False).agg(agg_rule)
3. 执行合并(可加列标识避免混淆)
如果存在大量通用列名,可在合并前给每个表的非Country列加来源前缀,从根源避免列名冲突;也可在merge时指定后缀区分来源:
# 可选操作:给非Country列加来源前缀,彻底避免重名问题 # prefixes = ['pop_', 'eco_', 'edu_', 'agg_', 'corr_', 'cyber_'] # for i in range(len(cleaned_dfs)): # df = cleaned_dfs[i] # df.columns = [f"{prefixes[i]}{col}" if col != 'Country' else col for col in df.columns] # cleaned_dfs[i] = df # 执行合并 df_merged = reduce(lambda left,right: pd.merge( left, right, on='Country', how='outer' ), cleaned_dfs)
4. 合并后抽样校验
随机抽取几个在多个表中都存在的国家,对比原表和合并表的数值,确认无错位:
# 替换为你确认在多个原表中有数据的国家名 check_list = ['China', 'United States', 'Germany'] for country in check_list: print(f"==== 校验国家:{country} ====") merged_val = df_merged[df_merged['Country']==country].iloc[0].to_dict() print("合并后取值:", merged_val)
若校验仍存在异常,优先检查是否存在未被别名映射覆盖的同国异名、或国家名存在肉眼难辨的特殊字符(如零宽空格),可通过打印每个国家名的字符编码逐一排查。
内容的提问来源于stack exchange,提问作者intellgirl
相关产品推荐
相关产品推荐

