直接用pandas.concat()拼接多个pd.read_excel()读取的dataframe即可,但必须统一列名、过滤空表、显式指定sheet_name=none读所有工作表(而非默认只读第一个),并设置ignore_index=true和sort=false以避免索引重复与列序错乱。

直接用 pandas.concat() 拼接多个 pd.read_excel() 读取的 DataFrame 即可,但必须统一列名、处理空表、注意 sheet_name 参数行为——否则会静默丢数据或报 ValueError: No objects to concatenate。
读取所有工作表时别漏掉 sheet_name=None
默认只读第一个表(sheet_name=0),想批量读所有表,必须显式传 sheet_name=None,它返回的是 dict:键是表名,值是对应 DataFrame。
常见错误:写成 sheet_name='*' 或 sheet_name='all' —— 这俩都不合法,会直接报 KeyError。
实操建议:
- 用
pd.read_excel(file_path, sheet_name=None)一次性读入全部表 - 若只要特定几张表,传列表如
sheet_name=['Sheet1', 'Data'],比循环多次调用read_excel更快 - 遇到表名含空格或特殊字符,
read_excel能正常识别,不用额外清洗键名
合并前必须对齐列结构,否则 concat 会补 NaN
不同工作表字段名不一致(比如有的叫 'user_id',有的叫 'uid')、列顺序不同、甚至列数都不同——pd.concat() 默认按列名对齐,缺失列自动填 NaN,极易埋下分析隐患。
实操建议:
- 先检查各表列名:
list(sheets_dict.values())[0].columns和list(sheets_dict.values())[1].columns - 手动统一列名再合并,例如:
df.rename(columns={'uid': 'user_id', 'date_str': 'date'}, inplace=True) - 如果某些表缺关键列,用
df.assign(status='unknown')补常量列,比留NaN更可控 - 避免用
ignore_index=True掩盖索引混乱问题;先确认每张表的业务主键逻辑是否一致
pd.concat() 的 ignore_index 和 sort 参数很关键
不设 ignore_index=True 会导致最终 DataFrame 索引重复(每张表都从 0 开始),后续用 .loc 或分组易出错;而 sort=False 可防止 Pandas 自动重排列顺序(尤其当各表列顺序不一致时)。
实操建议:
- 强制重置索引:
pd.concat(dfs, ignore_index=True, sort=False) - 不要依赖默认
sort=True:它会按字母序重排所有列,可能把'amount'排到'amount_usd'前面,破坏业务阅读习惯 - 若需保留原始表来源信息,提前加一列:
df.assign(source_sheet=name),再 concat
最易被忽略的是空工作表——read_excel 对空表返回的是只有列名、0 行的 DataFrame,concat 不报错但可能让下游计算(如 .sum())结果为 0 而非 NaN。建议在 concat 前加一行过滤:dfs = [df for df in dfs if not df.empty]。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











