Jupyter Notebook处理德语评论数据集时字符编码乱码及报错问题
你之前所有转码、修复操作无效的根本原因:你在最初读取CSV生成DataFrame的环节,就已经用Windows系统默认的cp1252编码错误解码了原始文件字节,所有无法识别的字符已经被替换为Unicode替换符\ufffd(也就是你看到的�),此时原始字节信息已经永久丢失,后续任何编码转换、ftfy自动修复操作都不可能还原原始字符,所有嵌套转码报错也都是因为字符串里已经存在无法被cp1252等单字节编码识别的\ufffd导致的。
Windows系统默认文本编码为cp1252,当你调用open()或pandasread_csv()不指定encoding参数时,Python会自动调用系统默认编码读取文件,这就是你看到文件默认以cp1252打开的原因。德语客户评论类CSV文件常见编码包括带BOM的UTF-8(utf-8-sig)、ISO-8859-1(Latin-1)、cp1252、ISO-8859-15几类,靠默认编码读取很容易出错。
不要在已经读坏的DataFrame上做转码操作,从头重新读取原始文件,按以下步骤操作:
1. 检测文件真实编码
不要靠猜测判断编码,用chardet库直接读取原始文件字节检测编码,先安装依赖:
pip install chardet
运行以下检测代码,全程以二进制模式读取文件,避免提前解码损坏数据:
import chardet # 以二进制只读模式打开原始文件 with open('C:/Users/TinnerF/Dropbox/ResearchProjects/RawData/LIWC_Output.csv', 'rb') as f: # 读取前10万字节用于检测,大文件不需要全量读 raw_sample = f.read(100000) detect_res = chardet.detect(raw_sample) print(detect_res)
输出结果会包含检测到的编码格式和置信度,置信度高于0.9的结果可以直接使用。
2. 显式指定编码重新读取文件
拿到检测到的编码后,读取文件时必须显式传入encoding参数,跳过系统默认编码逻辑,以pandas读CSV为例:
import pandas as pd # 把encoding参数替换为上一步检测到的编码,比如检测到是utf-8-sig就填这个 df = pd.read_csv('C:/Users/TinnerF/Dropbox/ResearchProjects/RawData/LIWC_Output.csv', encoding='检测到的编码')
如果chardet检测置信度较低,可以按优先级逐个尝试德语区CSV常用编码:utf-8-sig(优先试,Windows下导出的UTF-8文件基本都是这个)> ISO-8859-1(单字节全映射编码,读任何文件都不会产生�替换符,只会显示特殊字符错版)> cp1252 > ISO-8859-15,直到文本里的德语特殊字符äöüßÄÖÜ正常显示为止。
3. 验证读取结果
读取完成后直接打印第一条评论验证:
print(df['text'].iloc[0])
正常情况下你之前看到的G�sten会显示为正确的Gästen,全文不会再出现�替换符,后续做主题建模的文本预处理就不会受编码问题影响。
- 永远不要在已经出现�的字符串上做转码操作,此时原始字节信息已经丢失,所有操作都是无效的,还会触发你之前遇到的编码报错。
- Windows环境下读写文本文件,不管是用原生
open()还是pandas、numpy等库的IO接口,永远显式指定encoding参数,不要依赖系统默认编码。 - 如果CSV是从Excel直接导出的,优先尝试
utf-8-sig和cp1252两个编码,这是Excel导出CSV的默认编码格式。
内容的提问来源于stack exchange,提问作者peanutbutterandjellyfish

