乱码不是Pandas的bug,而是编码声明与文件实际字节不匹配;必须用encoding='utf-8-sig'读取Excel保存的CSV(自动处理BOM),中文路径需用Path().resolve()构造,编码不确定时按utf-8-sig、gbk、gb18030顺序尝试。

直接说结论:乱码不是 Pandas 的 bug,而是编码声明和文件实际字节不匹配。关键不在“用什么函数”,而在“用什么 encoding 去读”——且必须和文件保存时的 encoding 对得上。
pd.read_csv() 必须显式指定 encoding='utf-8-sig' 才能正确读 Excel 保存的 CSV
Windows 上用 Excel “另存为 CSV UTF-8”生成的文件,开头自带 BOM()。如果只写 encoding='utf-8',Pandas 会把 BOM 当作真实字符读进第一列列名,变成 '\ufeff姓名';如果完全不写 encoding,Pandas 在 Windows 下常 fallback 到 gbk,直接报 UnicodeDecodeError。
正确做法是:
-
utf-8-sig是 Python 内置编码别名,它自动识别并跳过 BOM,后续仍按 UTF-8 解码 - 必须显式写出
encoding='utf-8-sig',不能简写成utf8或UTF-8 - 如果还报错,加
engine='python'—— 因为 Pandas 默认 C engine 会忽略encoding参数
示例:
立即学习“Python免费学习笔记(深入)”;
import pandas as pd
df = pd.read_csv('data.csv', encoding='utf-8-sig', engine='python')
中文路径导致报错?用 Path().resolve() 而不是字符串拼接
在 Windows 上直接传中文路径字符串给 pd.read_csv(),即使 encoding 正确,也可能因终端或 Python 启动环境的 locale 不一致而报错,比如 FileNotFoundError 或乱码路径。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
根本解法是交给 pathlib.Path 处理:
- 用
Path("D:/项目/用户数据.csv").resolve()构造路径对象,它内部调用 Windows Unicode API,不受终端编码影响 - 再把
.resolve()结果传给pd.read_csv(),而不是原始字符串 - 避免用
os.path.join()拼接中文路径——它不解决底层宽字符传递问题
错误写法:pd.read_csv("D:/项目/用户数据.csv", encoding='utf-8-sig')
正确写法:
from pathlib import Path
import pandas as pd
csv_path = Path("D:/项目/用户数据.csv").resolve()
df = pd.read_csv(csv_path, encoding='utf-8-sig', engine='python')
编码不确定时怎么安全探测?别只靠 chardet
chardet.detect() 只看文件前 N 字节,对小文件或 BOM 位置偏移的文件容易误判(比如把 gbk 误报成 utf-8)。更可靠的做法是按优先级尝试常见编码,并用 try/except 控制流程。
- 优先试
utf-8-sig(Excel、VS Code 导出主流) - 再试
gbk(老版记事本、国内多数 Excel 直接另存) - 最后试
gb18030(GBK 超集,兼容更多生僻汉字) - 不建议用
latin-1或errors='ignore'—— 它们不报错但中文变问号或方块,掩盖真实问题
片段示例:
encodings = ["utf-8-sig", "gbk", "gb18030"]
for enc in encodings:
try:
df = pd.read_csv("data.csv", encoding=enc, engine="python")
print(f"✅ 成功读取,编码:{enc}")
break
except UnicodeDecodeError:
continue
用 to_csv 保存后 Excel 能打开,但 Python 再读又乱码?检查 encoding 是否一致
这是典型“保存-读取”编码错配。例如你用 df.to_csv("out.csv", encoding="gbk") 保存,再用 pd.read_csv("out.csv", encoding="utf-8-sig") 去读,必然失败。
- 保存和读取必须用同一套 encoding,否则字节流无法还原
- 推荐统一用
utf-8-sig:保存时加index=False防止多一列索引;读取时配engine="python" - 如果上游数据源固定是 gbk(比如某业务系统导出),那就全程用
gbk,不要强行转 utf-8
特别注意:to_csv 默认不写 BOM,所以如果你用 encoding="utf-8" 保存,再用 encoding="utf-8-sig" 去读,反而会因期待 BOM 却没找到而失败。
BOM 和中文路径这两处是绝大多数人踩坑的起点,但它们不报明显错误,只表现为列名异常或文件找不到——容易误以为是数据问题,其实只是编码握手没对上。

















