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
encodings = ["utf-8","utf-8-sig", "iso-8859-1", "latin1", "cp1252"]
for encoding in encodings:
try:
dataframe = pd.read_csv(input_data_path,encoding=encoding)
break
except Exception as e: # or the error you receive
pass
3条答案
按热度按时间zrfyljdw1#
CSV文件是一个文本文件。如果它只包含ASCII字符,现在没有问题,大多数编码可以正确处理普通ASCII字符。非ASCII字符出现问题。示例
| 特征|Latin 1码|cp 850码|UTF-8编码|
| - -----|- -----|- -----|- -----|
| 埃|
'\xe9'
|'\x82'
|'\xc3\xa9'
|| è|
'\xe8'
|'\x8a'
|'\xc3\xa8'
|| ö|
'\xf6'
|'\x94'
|'\xc3\xb6'
|情况更糟,因为单字节字符集最多只能表示256个字符,而UTF-8可以表示所有字符。例如,除了 normal 引号字符
'
,unicode还包含它的左‘
或右’
版本,它们都没有在Latin 1或CP 850中表示。长话短说,没有什么比通用编码更好的了。但是某些编码,例如Latin 1具有特异性:它们可以解码任何字节。因此,如果声明Latin 1编码,则不会引发UnicodeDecodeError。简单地说,如果文件是UTF-8编码的,那么
é
看起来就像é
。正确的单引号是'â\x80\x99'
,但在Latin 1系统上显示为â
,在cp 1252系统上显示为’
。正如您所说的CP 1252,它是Latin 1的Windows变体,但它不具有能够解码任何字节的属性。
常见的方法是要求发送给您CSV文件的人使用相同的编码,并尝试使用该编码进行解码。那么对于编码不好的文件,您有两种解决方法。首先是CygnusX提出的一个:尝试以Latin 1结尾的编码序列,例如
encodings = ["utf-8-sig", "utf-8", "cp1252", "latin1"]
(顺便说一句,Latin 1是ISO-8859-1的别名,因此无需同时测试两者)。第二个是用
errors='replace'
打开文件:任何有问题的字节都将被替换字符替换。至少所有ASCII字符都是正确的:v09wglhw2#
你可以试试这个:https://stackoverflow.com/a/48556203/11246056
或者在try/except语句中迭代几种格式:
ruyhziif3#
这里有一个类似的解决方案,它循环不同类型的编码。一旦使用了有效的编码,就可以中断循环并继续!