读取 pandas 中的 csv 文件的编码类型
type of encoding to read csv files in pandas
好吧,所以我正在编写代码,我使用 pandas.read_csv
读取 CSV 文件,问题出在编码上,我使用的是 utf-8-sig
编码,这是有效的。但是,这给我带来了其他 CSV 文件的错误。我发现有些文件需要其他类型的编码,例如 cp1252
。问题是我无法将用户限制为与我的编码匹配的特定 CSV 类型。
那么有什么解决办法吗?例如,是否有适用于所有 CSV 的通用编码类型?或者我可以传递所有可能编码器的数组吗?
你可以试试这个:
或在 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 字符上。例子
character
Latin1 code
cp850 code
UTF-8 codes
é
'\xe9'
'\x82'
'\xc3\xa9'
è
'\xe8'
'\x8a'
'\xc3\xa8'
ö
'\xf6'
'\x94'
'\xc3\xb6'
情况更糟,因为单字节字符集最多可以表示 256 个字符,而 UTF-8 可以表示所有字符。例如在 normal 引号字符 '
旁边,unicode 包含它的左 ‘
或右 ’
版本,其中 none以 Latin1 或 CP850 表示。
长话短说,没有什么比得上通用编码了。但是某些编码,例如 Latin1 具有特殊性:它们可以解码任何字节。因此,如果您声明 Latin1 编码,则不会引发 UnicodeDecodeError。简单地说,如果文件是 UTF-8 编码的,é
将看起来像 é
。正确的单引号是 'â\x80\x99'
,但在 Latin1 系统上显示为 â
,在 cp1252 系统上显示为 ’
。
正如您所说的 CP1252,它是 Latin1 的 Windows 变体,但它不具备能够解码任何字节的 属性。
通常的方法是让发送给您的 CSV 文件的人使用相同的编码并尝试使用该编码进行解码。那么对于编码错误的文件,您有两种解决方法。第一个是 CygnusX 提出的:尝试一系列以 Latin1 结尾的编码,例如 encodings = ["utf-8-sig", "utf-8", "cp1252", "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...)
好吧,所以我正在编写代码,我使用 pandas.read_csv
读取 CSV 文件,问题出在编码上,我使用的是 utf-8-sig
编码,这是有效的。但是,这给我带来了其他 CSV 文件的错误。我发现有些文件需要其他类型的编码,例如 cp1252
。问题是我无法将用户限制为与我的编码匹配的特定 CSV 类型。
那么有什么解决办法吗?例如,是否有适用于所有 CSV 的通用编码类型?或者我可以传递所有可能编码器的数组吗?
你可以试试这个:
或在 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 字符上。例子
character | Latin1 code | cp850 code | UTF-8 codes |
---|---|---|---|
é | '\xe9' |
'\x82' |
'\xc3\xa9' |
è | '\xe8' |
'\x8a' |
'\xc3\xa8' |
ö | '\xf6' |
'\x94' |
'\xc3\xb6' |
情况更糟,因为单字节字符集最多可以表示 256 个字符,而 UTF-8 可以表示所有字符。例如在 normal 引号字符 '
旁边,unicode 包含它的左 ‘
或右 ’
版本,其中 none以 Latin1 或 CP850 表示。
长话短说,没有什么比得上通用编码了。但是某些编码,例如 Latin1 具有特殊性:它们可以解码任何字节。因此,如果您声明 Latin1 编码,则不会引发 UnicodeDecodeError。简单地说,如果文件是 UTF-8 编码的,é
将看起来像 é
。正确的单引号是 'â\x80\x99'
,但在 Latin1 系统上显示为 â
,在 cp1252 系统上显示为 ’
。
正如您所说的 CP1252,它是 Latin1 的 Windows 变体,但它不具备能够解码任何字节的 属性。
通常的方法是让发送给您的 CSV 文件的人使用相同的编码并尝试使用该编码进行解码。那么对于编码错误的文件,您有两种解决方法。第一个是 CygnusX 提出的:尝试一系列以 Latin1 结尾的编码,例如 encodings = ["utf-8-sig", "utf-8", "cp1252", "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...)