正确做法是先用glob或pathlib获取所有csv路径,逐个读取为dataframe并存入列表,再用pandas.concat一次性合并;需统一dtype、ignore_index=true、处理bom和列名异常,并在内存不足时分块读取转parquet。

用 pandas.concat 一次性读取所有 CSV,别用循环 append
直接循环 pd.read_csv() 再 .append() 是最慢的写法——每次 .append() 都会复制整个 DataFrame,几百个文件可能卡住或爆内存。正确做法是先收集所有 DataFrame 到列表,再用 pd.concat() 一次性合并。
- 用
glob.glob("*.csv")或pathlib.Path().glob("*.csv")获取全部路径,避免手动列文件名 - 统一指定
dtype(比如{"id": "str", "value": "float"}),防止同一列在不同文件中被推断成不同类型,导致concat报TypeError: cannot concatenate object - 加
ignore_index=True重置行索引,否则保留各文件原始索引,后续按行操作容易出错
跳过 header 或统一用第一份文件的列名
如果所有 CSV 确实结构完全一致,但部分文件误带了重复 header 行(比如导出工具多写了一次表头),read_csv(..., skiprows=1) 会出错——因为有的文件没多那行。更稳的做法是:只对第一个文件读 header,其余全用 header=None + names=first_cols。
- 先
pd.read_csv(files[0], nrows=0)拿列名(快且不加载数据) - 后续每个
pd.read_csv(f, header=None, skiprows=1, names=first_cols),跳过各行首行,强制用统一列名 - 若存在空文件,加
error_bad_lines=False(旧版)或on_bad_lines="skip"(pandas ≥1.4)防中断
内存不够时,分批合并 + 直接写入 Parquet
几百个 CSV 总量超 1GB 后,pd.concat 容易触发 MemoryError。与其调大 swap 或换机器,不如绕过全量加载:
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
- 用
pd.read_csv(..., chunksize=50000)分块读单个文件,concat当前块 → 累加到临时buffer,每满 20 万行就to_parquet("merged.part1.parq", engine="pyarrow", compression="snappy") - 最终用
pd.read_parquet()拼接多个 part 文件,比 CSV 快 3–5 倍,且支持列裁剪(columns=["a","b"]) - 注意
pyarrow需单独pip install pyarrow,fastparquet对中文路径偶尔报错,优先选前者
路径含中文或空格时,glob 和 read_csv 都要加 encoding="utf-8-sig"
Windows 下用 Excel 导出的 CSV 经常带 BOM,不处理会导致第一列列名开头出现 \ufeffid,后续 df["id"] 报 KeyError;空格路径在某些 shell 环境下会被截断。
-
glob.glob("data/*.csv", recursive=True)在中文路径下基本可用,但保险起见改用pathlib.Path("data").rglob("*.csv") - 每个
pd.read_csv(f, encoding="utf-8-sig"),显式声明编码,比依赖默认更可靠 - 如果列名里混有不可见字符(比如从网页复制来的 CSV),用
df.columns = df.columns.str.strip()清理前后空格
真正耗时的不是代码行数,而是对齐列类型、处理编码、避开全量加载——这些细节漏一个,跑一半就失败。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










