多索引DataFrame缺失索引补全与合并报错问题求助
解决多层索引DataFrame合并报错并补全缺失值为0
问题原因
你遇到的InvalidIndexError,本质是多层索引里的Win/Loose项大小写不统一(比如win小写、Loose首字母大写),导致索引无法正确对齐;同时join="inner"会只保留两个DataFrame共有的索引,完全不符合你补全缺失项的需求。
解决方案
步骤1:统一索引大小写(消除匹配障碍)
先把两个DataFrame的Win/Loose索引项统一成相同格式(比如全小写),避免大小写差异导致的索引不匹配:
# 统一old_results的Win/Loose索引为小写 old_results.index = old_results.index.set_levels( old_results.index.get_level_values(1).str.lower(), level=1 ) # 统一new_results的Win/Loose索引为小写 new_results.index = new_results.index.set_levels( new_results.index.get_level_values(1).str.lower(), level=1 )
步骤2:合并并填充缺失值为0
用join='outer'保留所有索引项,再用fillna(0)把缺失的2024数据补为0:
# 合并两个DataFrame,保留全部索引 merged_results = pd.concat([old_results, new_results], axis=1, join='outer') # 将缺失值填充为0 merged_results = merged_results.fillna(0) # 可选:把Win/Loose索引恢复为首字母大写格式 merged_results.index = merged_results.index.set_levels( merged_results.index.get_level_values(1).str.capitalize(), level=1 )
完整可运行代码
import pandas as pd # 原始数据 old_results = pd.DataFrame({'name': ['Soccer','Soccer','baseball','baseball', 'basketball', 'basketball'], 'Win/Loose':['win','Loose','win','Loose','win','Loose'], '2022':[5,7,2,5,9,4], '2023':[6,5,3,4,7,6]}).set_index(['name', 'Win/Loose']) new_results = pd.DataFrame({'name': ['Soccer','Soccer','baseball','baseball', 'basketball'], 'Win/Loose':['win','Loose','win','Loose','win'], '2024':[8,4,6,1,13]}).set_index(['name', 'Win/Loose']) # 统一索引大小写 old_results.index = old_results.index.set_levels(old_results.index.get_level_values(1).str.lower(), level=1) new_results.index = new_results.index.set_levels(new_results.index.get_level_values(1).str.lower(), level=1) # 合并并填充缺失值 merged_results = pd.concat([old_results, new_results], axis=1, join='outer').fillna(0) # 恢复索引大小写(可选) merged_results.index = merged_results.index.set_levels(merged_results.index.get_level_values(1).str.capitalize(), level=1) print(merged_results)
最终输出
2022 2023 2024 name Win/Loose Soccer Win 5.0 6.0 8.0 Loose 7.0 5.0 4.0 baseball Win 2.0 3.0 6.0 Loose 5.0 4.0 1.0 basketball Win 9.0 7.0 13.0 Loose 4.0 6.0 0.0
替代方案:用combine_first快速补全
如果只需要用新数据补全旧数据的缺失项,也可以用combine_first:
# 统一索引大小写后执行 merged_results = new_results.combine_first(old_results).fillna(0)
内容的提问来源于stack exchange,提问作者user13017275
相关产品推荐
相关产品推荐

