问题描述
好的,所以我正在编写一个代码,我使用 pandas.read_csv
读取 CSV 文件,问题出在编码上,我使用的是 utf-8-sig
编码,并且这是有效的。但是,这给我带来了其他 CSV 文件的错误。我发现有些文件需要其他类型的编码,例如 cp1252
。问题是我无法将用户限制为与我的编码匹配的特定 CSV 类型。
那么有什么解决办法吗?例如,是否有适用于所有 CSV 的通用编码类型?或者我可以传递所有可能的编码器的数组吗?
解决方法
你可以试试这个:https://stackoverflow.com/a/48556203/11246056
或者在 try/except 语句中迭代几种格式:
encodings = ["utf-8-sig,"cp1252","iso-8859-1","latin1"]
try:
for encoding in encodings:
pandas.read_csv(...,encoding=encoding,...)
...
except ValueError: # or the error you receive
continue
,
CSV 文件是文本文件。如果它只包含 ASCII 字符,现在没问题,大多数编码都可以正确处理纯 ASCII 字符。问题出现在非 ASCII 字符上。例子
字符 | Latin1 代码 | cp850 代码 | UTF-8 代码 |
---|---|---|---|
é | '\xe9' |
'\x82' |
'\xc3\xa9' |
è | '\xe8' |
'\x8a' |
'\xc3\xa8' |
ö | '\xf6' |
'\x94' |
'\xc3\xb6' |
情况更糟,因为单字节字符集最多可以表示 256 个字符,而 UTF-8 可以表示所有字符。例如,在普通引号字符 '
旁边,unicode 包含它的左 ‘
或右 ’
版本,它们都没有用 Latin1 或 CP850 表示。
长话短说,没有什么能比得上通用编码。但是某些编码,例如 Latin1 有一个特殊性:它们可以解码任何字节。因此,如果您声明 Latin1 编码,则不会引发 UnicodeDecodeError。如果文件是 UTF-8 编码的,那么 é
将看起来像 é
。正确的单引号是 'â\x80\x99'
,但在 Latin1 系统上显示为 â
,在 cp1252 系统上显示为 ’
。
正如您所说的 CP1252,它是 Latin1 的 Windows 变体,但它不具有能够解码任何字节的特性。
常见的方法是要求向您发送 CSV 文件的人使用相同的编码并尝试使用该编码进行解码。然后,对于编码错误的文件,您有两种解决方法。第一个是 CygnusX 提出的:尝试一系列以 Latin1 结尾的编码,例如 encodings = ["utf-8-sig","utf-8","latin1"]
(顺便说一句,Latin1 是 ISO-8859-1 的别名,因此无需测试两者)。
第二种是用errors='replace'
打开文件:任何有问题的字节都将被替换字符替换。至少所有 ASCII 字符都是正确的:
with open(filename,encoding='utf-8-sig',errors='replace') as file:
fd = pd.read_csv(file,other_parameters...)