Pandas中合并两个多级索引无结果返回的问题求助
兄弟,我太懂你这种多级索引合并踩坑的痛苦了!尤其是还得保留指定列,之前操作没结果大概率是合并键的数据类型不匹配或者合并逻辑没搞对,给你一步步捋清楚解决方案:
解决Pandas多级索引DataFrame合并问题(保留指定0列)
一、先排查核心坑:数据类型不匹配
这是多级索引合并失败的头号原因!比如你的Cif在al_staff里是字符串类型,在new里是整数类型,哪怕值看起来完全一样,Pandas也会判定为不匹配,直接返回空结果。
先打印两个DataFrame的索引类型和列信息确认:
# 检查al_staff的索引类型和列 print("al_staff的Cif索引类型:", al_staff.index.get_level_values('Cif').dtype) print("al_staff的ye索引类型:", al_staff.index.get_level_values('ye').dtype) print("al_staff的列:", al_staff.columns.tolist()) # 检查new的索引类型和列 print("new的Cif索引类型:", new.index.get_level_values('Cif').dtype) print("new的ye索引类型:", new.index.get_level_values('ye').dtype) print("new的列:", new.columns.tolist())
如果发现类型不一致,立刻统一!比如把Cif都转成字符串(根据你的实际数据调整):
# 统一al_staff的Cif类型为字符串 al_staff.index = al_staff.index.set_levels(al_staff.index.get_level_values('Cif').astype(str), level='Cif') # 统一new的Cif类型为字符串 new.index = new.index.set_levels(new.index.get_level_values('Cif').astype(str), level='Cif')
另外还要检查索引名称是否一致!比如一个叫CIF(全大写),一个叫Cif(首字母大写),也要统一:
# 把new的索引名称改成和al_staff一致 new.index.set_names(['Cif', 'ye'], inplace=True)
二、正确的合并操作(保留al_staff的0列)
不需要折腾重置索引,直接用索引合并更高效,而且能确保保留al_staff的所有列(包括那两个0列):
# 左连接:以al_staff为基准,保留它的所有行和列,匹配new中对应Cif+ye的数据 merged_df = al_staff.merge( new, left_index=True, # 用al_staff的多级索引当合并键 right_index=True, # 用new的多级索引当合并键 how='left', # 关键!左连接才会保留al_staff的所有数据 suffixes=('_al', '_new') # 有重名列的话自动加后缀区分 )
如果你之前已经重置了索引,那合并时要明确指定on=['Cif', 'ye'],并且确保这两列类型一致:
# 重置索引 al_staff_reset = al_staff.reset_index() new_reset = new.reset_index() # 先统一类型(比如Cif转字符串,ye转整数) al_staff_reset['Cif'] = al_staff_reset['Cif'].astype(str) new_reset['Cif'] = new_reset['Cif'].astype(str) al_staff_reset['ye'] = al_staff_reset['ye'].astype(int) new_reset['ye'] = new_reset['ye'].astype(int) # 合并 merged_df = al_staff_reset.merge( new_reset, on=['Cif', 'ye'], how='left', suffixes=('_al', '_new') ) # 可选:重新设置回多级索引 merged_df = merged_df.set_index(['Cif', 'ye'])
三、验证合并结果
合并后一定要检查是否符合预期:
# 查看合并后的所有列,确认那两个0列是否保留 print("合并后的列:", merged_df.columns.tolist()) # 检查匹配成功的行数(如果是左连接,总行数应该和al_staff一致) print("合并后总行数:", merged_df.shape[0]) print("匹配到new数据的行数:", merged_df.dropna(subset=new.columns.tolist()).shape[0])
内容的提问来源于stack exchange,提问作者Iwan
相关产品推荐
相关产品推荐

