CSV中文乱码需先查真实编码,用chardet探测或命令行验证;读取时按文件实际编码指定encoding参数,如gbk、utf-8-sig等;写入时注意BOM适配目标环境。

读取CSV时中文变问号或方块?先查文件真实编码
乱码不是Pandas的问题,而是你没告诉它文件用的什么编码。系统默认编码(比如Windows的gbk、Linux/macOS的utf-8)和文件实际编码不一致时,pd.read_csv()就会瞎猜——猜错就乱码。
- 别靠“感觉”选编码:用命令行快速验证,
file -i filename.csv(Linux/macOS)或chcp配合type filename.csv | more(Windows)粗判 - 更稳的方法是用
chardet库探测:chardet.detect(open('data.csv', 'rb').read(10000)),看encoding字段返回值(注意:只读前10KB,大文件可能不准) - 常见坑:Excel另存为CSV时默认用
gbk(中文Windows),但Pandas在macOS上跑会直接按utf-8读——结果首行标题就变???
pd.read_csv()里encoding参数填什么?别硬背,分场景记
encoding不是选“最流行”的,是选“文件写入时用的那个”。填错轻则警告,重则UnicodeDecodeError中断。
- Windows用户处理本地导出的CSV:优先试
encoding='gbk'或encoding='gb2312';若报错'gbk' codec can't decode byte,说明有UTF-8 BOM头,改用encoding='utf-8-sig' - 从Linux服务器下载的CSV:大概率是
utf-8,但若含中文路径或旧系统日志,可能混latin-1(它能强行解码所有字节,不报错但内容错,慎用) - 不确定时,用
errors='replace'兜底:pd.read_csv('x.csv', encoding='utf-8', errors='replace'),把乱码位置替换成,至少不崩,方便后续定位
读进来还是乱码?可能是列内混编码,得逐列清洗
有些日志或爬虫数据,同一列里不同行用了不同编码(比如前几行是UTF-8,后面几行是GBK),pd.read_csv()全局指定encoding救不了——它只能按一种规则解整个文件。
- 先用
encoding='latin-1'暴力读入(它不会报错),检查df.iloc[0].apply(type)确认是否全为str,再对疑似乱码列单独处理 - 对单列转码:拿到原始字节再解码,例如
df['col'].apply(lambda x: x.encode('latin-1').decode('gbk', errors='ignore'))(前提是你知道这列本该是gbk) - 性能提醒:
apply()+encode/decode在百万行上很慢;真要批量处理,改用numpy.vectorize或提前用Python脚本做预清洗
保存时又变乱码?encoding和BOM必须配套
读对了,写出来又乱,多半是保存时没匹配目标环境的预期。Excel打开乱码,90%是因为没加BOM头。
立即学习“Python免费学习笔记(深入)”;
- 给Windows用户看的CSV:用
df.to_csv('out.csv', encoding='utf-8-sig')(utf-8-sig会在开头写BOM,Excel才认它是UTF-8) - 给Linux程序读的CSV:用
encoding='utf-8',别加BOM,否则awk/sed可能把BOM当脏字符 - 避免二次污染:如果源文件是
gbk,你用utf-8-sig保存后发给同事,他用记事本打开正常,但用Python再读就得指定utf-8-sig,否则开头多一个\ufeff
编码问题没有银弹。最麻烦的永远是混合来源的数据——比如数据库导出+手工编辑+爬虫拼接,这时候靠自动探测不如人工抽样验证三行:开头、中间、结尾各一行,分别看repr()输出,比什么都准。










