拼接索引顺序不同的Pandas多级索引DataFrame时索引名称丢失问题
Pandas多级索引DataFrame拼接后索引名称丢失问题解决
问题描述
有两个需拼接的Pandas多级索引DataFrame,二者索引元素完全相同,但索引层级顺序不同:第一个的索引名称为['id_a', 'id_b', 'id_c'],第二个为['id_a', 'id_c', 'id_b']。使用pd.concat([df, df2])拼接后,结果仅保留id_a作为索引名称,其余两个层级名称变为None。
复现步骤
import pandas as pd # 创建第一个DataFrame idx = pd.MultiIndex.from_product( [['A1', 'A2', 'A3'], ['B1', 'B2', 'B3'], ['C1', 'C2', 'C3']], names=['a', 'b', 'c']) cols = ['2010', '2020'] df = pd.DataFrame(1, idx, cols) # 创建索引顺序不同的第二个DataFrame idx = pd.MultiIndex.from_product( [['A1', 'A2', 'A3'], ['C1', 'C2', 'C3'], ['B1', 'B2', 'B3']], names=['a', 'c', 'b']) df2 = pd.DataFrame(2, idx, cols) result = pd.concat([df, df2])
现象
拼接后的result.index.names为FrozenList(['a', None, None]),仅第一个层级名称保留,其余两个层级名称丢失。
原因分析
pd.concat处理多级索引时,按层级的位置合并索引名称:只有当两个DataFrame对应位置的层级名称完全一致时,才会保留该名称;若对应位置名称不同,该层级名称会被设为None。本案例中,第一个层级名称都是a所以保留,第二个层级df是b、df2是c,第三个层级df是c、df2是b,位置对应名称不匹配,导致这两个层级名称丢失。
解决方案
方法1:统一索引层级顺序后拼接
将第二个DataFrame的索引层级调整为与第一个一致,确保对应位置的层级名称相同,再执行拼接:
# 调整df2的索引层级顺序为['a', 'b', 'c'],与df匹配 df2_aligned = df2.reorder_levels(['a', 'b', 'c']) result = pd.concat([df, df2_aligned]) # 验证索引名称 print(result.index.names) # 输出: FrozenList(['a', 'b', 'c'])
方法2:拼接后手动设置索引名称
若无需调整索引层级顺序,可在拼接后手动指定所有层级的名称(需明确各层级实际含义):
result = pd.concat([df, df2]) # 根据实际逻辑设置层级名称 result.index.names = ['a', 'mixed_b_c', 'mixed_c_b']
优先推荐方法1,能保证索引逻辑的一致性,避免后续数据处理出现歧义。
内容的提问来源于stack exchange,提问作者Tobias Lorenz
相关产品推荐
相关产品推荐

