Pandas折叠含Unnamed的MultiIndex列实现单层名称访问
pandas双层表头读取后折叠Unnamed层级通用方案
核心逻辑是自动识别多层列索引中pandas自动生成的Unnamed: X_level_Y占位符(这类值对应表格中跨列表头导致的空表头单元格),过滤掉占位层级后自动适配列名格式,无需手动指定列位置、适配任意层数的多层表头,且完整保留所有列数据。
基础版本(保留多层有效表头结构)
该版本仅折叠存在空值的Unnamed层级,原本存在多层有效表头的列(比如示例中Cat1/Cat2下的a/b/c/d列)仍保留元组形式的多层索引,仅将只有单层有效名称的列(code、Total列)转为单值列名,支持直接用df['code']、df['Total']访问:
import re import pandas as pd # 预编译正则,精准匹配pandas自动生成的Unnamed占位符固定格式:Unnamed: 数字_level_数字 unnamed_pattern = re.compile(r"^Unnamed: \d+_level_\d+$") def clean_multi_cols(col_tuple): valid_levels = [] for val in col_tuple: s_val = str(val) # 仅过滤自动生成的占位符,不影响用户自定义的同开头列名 if not unnamed_pattern.match(s_val): valid_levels.append(val) # 单有效层级返回单值,多有效层级返回元组保留多层结构 return valid_levels[0] if len(valid_levels) == 1 else tuple(valid_levels) # 读取文件后直接应用列清洗 df = pd.read_excel(file, sheet_name=sheet, header=[0,1]) df.columns = df.columns.map(clean_multi_cols)
处理示例表格后的列索引效果:
- 原
('Unnamed: 0_level_0', 'code')→ 列名code - 原
('Cat 1', 'a')→ 列名('Cat 1', 'a')(原有多层分类结构不变) - 原
('Total','Unnamed: 8_level_1')→ 列名Total
可选版本(全列单层访问)
如果需要所有列都支持单字符串名称访问,可以将多层有效名称拼接为下划线分隔的单层列名,不会丢失任何表头信息:
import re import pandas as pd unnamed_pattern = re.compile(r"^Unnamed: \d+_level_\d+$") def clean_multi_cols_flat(col_tuple): valid_levels = [] for val in col_tuple: s_val = str(val) if not unnamed_pattern.match(s_val): valid_levels.append(s_val) return "_".join(valid_levels) df = pd.read_excel(file, sheet_name=sheet, header=[0,1]) df.columns = df.columns.map(clean_multi_cols_flat)
处理后示例表格的列名依次为:code、Cat 1_a、Cat 1_b、Cat 1_c、Cat 1_d、Cat 2_a、Cat 2_b、Cat 2_c、Total,所有列均可直接通过单字符串索引访问。
方案优势
- 无需提前预知Unnamed占位符出现的层级和列位置,支持2层及以上的任意多层表头场景
- 不会删除任何列,所有原始数据完整保留
- 用正则精准匹配pandas自动生成的占位符,不会误处理用户自定义的同开头列名
- 无硬编码值,适配不同结构的同类Excel表格读取场景
内容的提问来源于stack exchange,提问作者thosphor
相关产品推荐
相关产品推荐

