使用Python在Pandas中读取CSV文件时的UnicodeDecodeError

Tra*_*VOX 329 python csv unicode dataframe pandas

我正在运行一个处理30,000个类似文件的程序.随机数量正在停止并产生此错误......

   File "C:\Importer\src\dfman\importer.py", line 26, in import_chr
     data = pd.read_csv(filepath, names=fields)
   File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 400, in parser_f
     return _read(filepath_or_buffer, kwds)
   File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 205, in _read
     return parser.read()
   File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 608, in read
     ret = self._engine.read(nrows)
   File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 1028, in read
     data = self._reader.read(nrows)
   File "parser.pyx", line 706, in pandas.parser.TextReader.read (pandas\parser.c:6745)
   File "parser.pyx", line 728, in pandas.parser.TextReader._read_low_memory (pandas\parser.c:6964)
   File "parser.pyx", line 804, in pandas.parser.TextReader._read_rows (pandas\parser.c:7780)
   File "parser.pyx", line 890, in pandas.parser.TextReader._convert_column_data (pandas\parser.c:8793)
   File "parser.pyx", line 950, in pandas.parser.TextReader._convert_tokens (pandas\parser.c:9484)
   File "parser.pyx", line 1026, in pandas.parser.TextReader._convert_with_dtype (pandas\parser.c:10642)
   File "parser.pyx", line 1046, in pandas.parser.TextReader._string_convert (pandas\parser.c:10853)
   File "parser.pyx", line 1278, in pandas.parser._string_box_utf8 (pandas\parser.c:15657)
 UnicodeDecodeError: 'utf-8' codec can't decode byte 0xda in position 6: invalid    continuation byte
Run Code Online (Sandbox Code Playgroud)

这些文件的来源/创建都来自同一个地方.什么是纠正此问题以进行导入的最佳方法?

Ste*_*fan 692

read_csv需要一个encoding选项,以应对不同格式的文件.我主要使用read_csv('file', encoding = "ISO-8859-1"),或者encoding = "utf-8"用于阅读,一般utf-8用于to_csv.

你也可以使用其中一个alias选项'latin'而不是'ISO-8859-1'(参见python docs,也可以用于你可能遇到的其他许多编码).

请参阅相关的Pandas文档, 关于csv文件的python docs示例,以及有关SO的大量相关问题.

要检测编码(假设文件包含非ascii字符),您可以使用enca(参见手册页)或file -i(linux)或file -I(osx)(参见手册页).

  • 谢谢Stefan!我添加了`encoding ="ISO-8859-1"`并且它们导入完美. (66认同)
  • 谢谢`pd.read_csv('immigration.csv',encoding ="ISO-8859-1",engine ='python')`为我工作 (5认同)
  • 由于这是一个Windows问题,`cp1252`可能更适合`iso-8859-1`. (4认同)
  • 不要盲目地假设某个编码是正确的,只是因为没有抛出异常.您需要查看字符串并确定解释是否有意义.例如,如果你得到"hors d'½uvre"而不是"hors d'œuvre",你可能需要从ISO-8859-1切换到ISO-8859-15. (3认同)
  • 对我来说,编码是ANSI。为了弄清楚这一点,我在“记事本”中打开了csv,然后单击“另存为”,它在“保存”按钮旁边显示了编码。 (2认同)
  • @Ben这是一个很好的资源[每个开发人员应了解的Unicode和字符集](https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively -必须知道有关Unicode和字符集的任何借口/) (2认同)

Gil*_*gio 35

最简单的解决方案:

  • Sublime文本编辑器中打开csv文件.
  • 以utf-8格式保存文件.

在sublime中,单击文件 - >使用编码保存 - > UTF-8

然后,您可以照常阅读您的文件:

import pandas as pd
data = pd.read_csv('file_name.csv', encoding='utf-8')
Run Code Online (Sandbox Code Playgroud)

编辑1:

如果有很多文件,那么您可以跳过sublime步骤.

只需阅读文件即可

data = pd.read_csv('file_name.csv', encoding='utf-8')
Run Code Online (Sandbox Code Playgroud)

和其他不同的编码类型是:

encoding = "cp1252"
encoding = "ISO-8859-1"
Run Code Online (Sandbox Code Playgroud)

  • 问题解释说有30,000个这样的文件.手动打开每个文件是不切实际的. (8认同)
  • 至少对于一个文件来说,这似乎对我有用! (2认同)
  • 使用保存和编码的替代解决方案非常有帮助!以下是如何将其用于 VSCode /sf/ask/2105791901/ (2认同)
  • 感谢您的提示,通过 _VS Code_ 保存 CSV 文件对我来说很有效。 (2认同)
  • 非常适合我。 (2认同)

Ser*_*sta 16

Pandas允许指定编码,但不允许忽略错误而不是自动替换有问题的字节.所以没有一种尺寸适合所有方法,但根据实际使用情况不同的方式.

  1. 您知道编码,并且文件中没有编码错误.太棒了:你只需要指定编码:

    file_encoding = 'cp1252'        # set file_encoding to the file encoding (utf8, latin1, etc.)
    pd.read_csv(input_file_and_path, ..., encoding=file_encoding)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 您不希望被编码问题困扰,只想加载该死的文件,无论某些文本字段是否包含垃圾.好吧,你只需要使用Latin1编码,因为它接受任何可能的字节作为输入(并将其转换为相同代码的unicode字符):

    pd.read_csv(input_file_and_path, ..., encoding='latin1')
    
    Run Code Online (Sandbox Code Playgroud)
  3. 您知道大多数文件都是使用特定编码编写的,但它也包含编码错误.一个真实世界的例子是一个UTF8文件,该文件是用非utf8编辑器编辑的,其中包含一些具有不同编码的行.Pandas没有提供特殊的错误处理,但Python open函数有(假设是Python3),并且read_csv接受像object这样的文件.这里使用的典型错误参数'ignore'只是抑制有问题的字节或(恕我直言更好)'backslashreplace'用Python的反斜杠转义序列替换有问题的字节:

    file_encoding = 'utf8'        # set file_encoding to the file encoding (utf8, latin1, etc.)
    input_fd = open(input_file_and_path, encoding=file_encoding, errors = 'backslashreplace')
    pd.read_csv(input_fd, ...)
    
    Run Code Online (Sandbox Code Playgroud)

  • 迟到的答案,但针对 [重复问题](/sf/ask/3623401981/)... (2认同)

con*_* yu 12

chardet您始终可以尝试先使用orcchardet或检测文件的编码charset-normalizer

from pathlib import Path
import chardet

filename = "file_name.csv"
detected = chardet.detect(Path(filename).read_bytes())
# detected is something like {'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}

encoding = detected.get("encoding")
assert encoding, "Unable to detect encoding, is it a binary file?"

df = pd.read_csv(filename, encoding=encoding)

Run Code Online (Sandbox Code Playgroud)


小智 11

with open('filename.csv') as f:
   print(f)
Run Code Online (Sandbox Code Playgroud)

执行此代码后,您将找到“ filename.csv”的编码,然后执行以下代码

data=pd.read_csv('filename.csv', encoding="encoding as you found earlier"
Run Code Online (Sandbox Code Playgroud)

你去


小智 8

就我而言,USC-2 LE BOM根据 Notepad++ ,文件具有编码。它适用encoding="utf_16_le"于蟒蛇。

希望,它有助于为某人更快地找到答案。


Fle*_*weh 8

这是针对所述问题的更通用的脚本方法。

import pandas as pd

encoding_list = ['ascii', 'big5', 'big5hkscs', 'cp037', 'cp273', 'cp424', 'cp437', 'cp500', 'cp720', 'cp737'
                 , 'cp775', 'cp850', 'cp852', 'cp855', 'cp856', 'cp857', 'cp858', 'cp860', 'cp861', 'cp862'
                 , 'cp863', 'cp864', 'cp865', 'cp866', 'cp869', 'cp874', 'cp875', 'cp932', 'cp949', 'cp950'
                 , 'cp1006', 'cp1026', 'cp1125', 'cp1140', 'cp1250', 'cp1251', 'cp1252', 'cp1253', 'cp1254'
                 , 'cp1255', 'cp1256', 'cp1257', 'cp1258', 'euc_jp', 'euc_jis_2004', 'euc_jisx0213', 'euc_kr'
                 , 'gb2312', 'gbk', 'gb18030', 'hz', 'iso2022_jp', 'iso2022_jp_1', 'iso2022_jp_2'
                 , 'iso2022_jp_2004', 'iso2022_jp_3', 'iso2022_jp_ext', 'iso2022_kr', 'latin_1', 'iso8859_2'
                 , 'iso8859_3', 'iso8859_4', 'iso8859_5', 'iso8859_6', 'iso8859_7', 'iso8859_8', 'iso8859_9'
                 , 'iso8859_10', 'iso8859_11', 'iso8859_13', 'iso8859_14', 'iso8859_15', 'iso8859_16', 'johab'
                 , 'koi8_r', 'koi8_t', 'koi8_u', 'kz1048', 'mac_cyrillic', 'mac_greek', 'mac_iceland', 'mac_latin2'
                 , 'mac_roman', 'mac_turkish', 'ptcp154', 'shift_jis', 'shift_jis_2004', 'shift_jisx0213', 'utf_32'
                 , 'utf_32_be', 'utf_32_le', 'utf_16', 'utf_16_be', 'utf_16_le', 'utf_7', 'utf_8', 'utf_8_sig']

for encoding in encoding_list:
    worked = True
    try:
        df = pd.read_csv(path, encoding=encoding, nrows=5)
    except:
        worked = False
    if worked:
        print(encoding, ':\n', df.head())
Run Code Online (Sandbox Code Playgroud)

首先是 Python 版本可用的所有标准编码(在本例中为 3.7 python 3.7 标准编码)。此处提供了不同 python 版本的标准编码的可用 python 列表:Helpful Stack overflow answer

在一小块数据上尝试每种编码;只打印工作编码。输出是显而易见的。此输出还解决了这样的问题,即像“latin1”这样的编码应该有任何错误,但不一定会产生想要的结果。

如果出现问题,我会尝试这种特定于有问题的CSV文件的方法,然后可能尝试将找到的工作编码用于所有其他文件。


Kun*_*nal 7

尝试更改编码。在我的情况下,encoding = "utf-16"工作。

df = pd.read_csv("file.csv",encoding='utf-16')


Jan*_*n33 6

尝试指定 engine='python'。它对我有用,但我仍在试图找出原因。

df = pd.read_csv(input_file_path,...engine='python')
Run Code Online (Sandbox Code Playgroud)


小智 5

对此苦苦挣扎了一段时间,并认为我会发布这个问题,因为这是第一个搜索结果。将标签添加encoding="iso-8859-1"到 pandasread_csv不起作用,任何其他编码也不起作用,不断给出 UnicodeDecodeError。

如果您要传递文件句柄,则pd.read_csv(),需要将该encoding属性放在打开的文件上,而不是放在read_csv. 事后看来这是显而易见的,但却是一个难以追踪的微妙错误。


小智 5

在我的情况下,这适用于 python 2.7:

data = read_csv(filename, encoding = "ISO-8859-1", dtype={'name_of_colum': unicode}, low_memory=False) 
Run Code Online (Sandbox Code Playgroud)

而对于 python 3,只有:

data = read_csv(filename, encoding = "ISO-8859-1", low_memory=False) 
Run Code Online (Sandbox Code Playgroud)


Muj*_*que 5

我遇到的导致相同错误的另一个重要问题是:

_values = pd.read_csv("C:\Users\Mujeeb\Desktop\file.xlxs")
Run Code Online (Sandbox Code Playgroud)

^这一行导致了同样的错误,因为我正在使用方法读取 Excel 文件read_csv()。用于read_excel()读取 .xlxs


Pra*_*thi 5

请尝试添加

encoding='unicode_escape'
Run Code Online (Sandbox Code Playgroud)

这会有所帮助。为我工作。另外,请确保您使用了正确的分隔符和列名。

您可以从仅加载 1000 行开始以快速加载文件。