应先用chardet探测或编辑器查看真实编码,再按utf-8-sig、gbk、utf-8、latin-1优先级尝试读取,注意bom处理、中文分隔符及写入时encoding与excel兼容性。

怎么判断文件真实编码而不是瞎猜
乱码不是 pd.read_csv() 有 bug,是你没告诉它文件实际用的什么字节规则。Windows 上 Excel 导出的中文 CSV 多是 gbk 或 gb2312;VS Code 或 Python 脚本生成的常带 BOM,得用 utf-8-sig;Linux 日志可能混着 latin-1(它不会报错,但中文变 ,可辅助反推)。别靠经验硬套,先查:
- 用
chardet快速探测:import chardet with open('data.csv', 'rb') as f: print(chardet.detect(f.read(10000)))注意只读前 10KB,大文件可能不准 - 在 VS Code / Notepad++ 里直接看右下角编码标识
- Mac/Linux 下可用
file -i data.csv粗判
encoding 参数填什么才不崩、不乱、不丢字
填对 encoding 是基础,但细节决定成败:
-
utf-8-sig必须写全,不能只写utf-8—— 否则 BOM(\ufeff)残留会卡在列名开头,变成ufeff姓名 -
gbk和gb2312在中文 Windows 场景下优先试,但若报'gbk' codec can't decode byte,大概率是文件其实是utf-8-sig -
latin-1是兜底选项:它能强行解所有字节,不抛UnicodeDecodeError,但中文全变,仅适合快速确认是否真为 GBK 编码 - 大小写不敏感,但统一用小写更稳妥,比如写
encoding='utf-8',别写UTF-8
sep 和 encoding 打架了怎么办
encoding 错会导致分隔符识别失效。比如一个中文逗号(,)被错误按 utf-8 解成两个无效字节,pd.read_csv() 就找不到分隔符,整行塞进第一列。
- 先用文本编辑器以你怀疑的 encoding 重新打开文件,肉眼确认分隔符是不是英文逗号
,、制表符\t、竖线|,或中文逗号, - 如果是中文逗号,显式加
sep=','(注意是中文字符) - 如果列名本身含逗号(如
"用户,姓名"),必须配quotechar='"'且原始文件字段用双引号包裹 - Windows 路径中的反斜杠要写成
r'C:\data.csv'或'C:/data.csv',否则\n\t会被转义
批量读取多个 CSV 时怎么自动适配编码
手动跑 chardet 不现实。写个探测函数按优先级尝试,比硬编码更可靠:
def read_csv_auto(path):
for enc in ['utf-8-sig', 'gbk', 'utf-8', 'latin-1']:
try:
return pd.read_csv(path, encoding=enc)
except UnicodeDecodeError:
continue
raise ValueError(f'Cannot decode {path} with any known encoding')
- 顺序很重要:
utf-8-sig放最前,覆盖 Excel 另存为“CSV UTF-8”的常见场景 - 遇到同一列内混编码(比如爬虫数据前几行 UTF-8、后几行 GBK),全局
encoding无解,得先用latin-1暴力读入,再对单列单独转码:df['col'].apply(lambda x: x.encode('latin-1').decode('gbk', errors='ignore')) - 百万行以上慎用
apply+encode/decode,性能差;真要批量清洗,建议预处理脚本统一转码
最易被忽略的一点:BOM 不只是读的问题,写的时候也要配套。用 to_csv(encoding='gbk') 写的文件,Excel 双击能正常打开;但用 utf-8 写的,得加 BOM(即用 utf-8-sig)才能让 Excel 自动识别。否则,读对了,写出来别人打不开,等于白干。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











