用glob批量匹配Excel文件需注意路径转义与大小写问题,推荐跨平台写法[f for f in glob.glob("data/*") if f.lower().endswith(('.xlsx', '.xls'))],读取时指定engine='openpyxl',拼接前统一列名并reindex对齐,显式控制dtype和parse_dates避免类型错乱,大文件用生成器或chunksize防内存溢出。

用 glob 批量匹配 Excel 文件时,路径和扩展名容易出错
Windows 下反斜杠 \ 会被 Python 当作转义字符,直接写 "data\*.xlsx" 可能报 FileNotFoundError;Linux/macOS 则对大小写敏感,"*.XLSX" 匹配不到小写后缀文件。
稳妥做法是统一用正斜杠或 os.path.join,并用 glob.glob 的 recursive=False(默认)+ 显式指定大小写无关的通配:
- 推荐写法:
glob.glob("data/*.xls*")—— 同时覆盖.xlsx和.xls - 更健壮写法(跨平台):
[f for f in glob.glob("data/*") if f.lower().endswith(('.xlsx', '.xls'))] - 别漏掉
engine='openpyxl':读.xlsx时 pandas 默认引擎不支持样式,但列名读取不受影响;若文件含公式或特殊格式,显式加engine='openpyxl'更稳
pandas.concat 拼接前必须处理列名不一致问题
不同 Excel 表头可能有空格、大小写差异、顺序错乱甚至字段缺失,直接 concat(..., ignore_index=True) 会导致列错位或丢失数据。
关键不是“统一重命名”,而是“按语义对齐”:
- 先用
pd.read_excel(f, nrows=0)快速读表头,避免加载全量数据 - 标准化列名:
df.columns = df.columns.str.strip().str.lower().str.replace(r'[^a-z0-9_]', '_', regex=True) - 定义一个权威列名列表(如
["order_id", "product_name", "amount"]),拼接前用df.reindex(columns=canonical_cols, fill_value=pd.NA)对齐 —— 缺失列补NA,多余列丢弃 - 别用
join="outer":它会保留所有列,导致最终 DataFrame 出现大量Unnamed: X或重复字段
合并后日期/数字列类型错乱?这是 read_excel 的 dtype 自动推断陷阱
pandas 读 Excel 时对混合类型(比如某列前几行是空、中间是数字、最后是日期)常误判为 object,后续计算或导出就出问题。
解析 MySQL 8.0 的 DDL 脚本,并将表结构导出为 Excel 格式。适用于用户需将 MySQL 的 `CREATE TABLE` 语句转换为结构化的 Excel 文件场景,导出内容包含字段名、数据类型、长度及精度等信息。支持多张表的批量处理,每张表对应 Excel 中的一个独立工作表。适用于数据库文档编写、数据字典生成及模式分析等任务。
解决不能靠事后转换,得在读取阶段干预:
- 明确指定
dtype:如dtype={"amount": "float64", "order_date": "string"}(先读成字符串,再用pd.to_datetime(..., errors="coerce")统一处理) - 对疑似日期列,加
parse_dates=["order_date"]参数,比事后转换更可靠 - 如果某些文件该列为文本(如带前导零的订单号),务必设
dtype={"order_id": "string"},否则123456会被转成123456.0 - 注意:多个文件中同一列类型不一致时,
concat会自动升格为object,所以必须提前统一样本类型
大文件合并卡死或内存爆掉?别一次性全读进内存
单个 Excel 超 10 万行、或总文件数超 50 个时,[pd.read_excel(f) for f in files] 构建列表会吃光内存。
改用生成器 + 分块拼接:
- 用
pd.concat((pd.read_excel(f, dtype=dtype_cfg) for f in files), ignore_index=True)—— 小括号是 generator expression,不预加载全部 DataFrame - 对超大单文件,启用
chunksize:先读头几行定列名,再循环读块、对齐、追加到结果list,最后concat - 导出前删掉中间变量:
del df_list; gc.collect()(尤其 Windows 上 CPython 不会立刻释放) - 最后保存用
index=False,避免多一列无意义的行号
列名对齐和类型控制这两步漏掉任何一环,合并后的表看着像,查数或 join 时就会突然崩。实际跑通的关键不在“快”,而在每一步都做显式校验——比如读完每个文件后打个 print(f"{f}: {list(df.columns)}"),比调半天报错强得多。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










