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

时间:2013-08-11 12:06:25

标签: python pandas csv dataframe unicode

我正在运行一个处理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

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

23 个答案:

答案 0 :(得分:564)

read_csv使用encoding选项来处理不同格式的文件。我主要使用read_csv('file', encoding = "ISO-8859-1")encoding = "utf-8"进行阅读,utf-8通常使用to_csv

您还可以使用其中一个alias选项,例如'latin'而不是'ISO-8859-1'(请参阅python docs,也可以使用其他许多其他编码)。

relevant Pandas documentationpython docs examples on csv files,以及关于SO的大量相关问题。

要检测编码(假设文件包含非ascii字符),您可以使用enca(请参阅man page)或file -i(linux)或file -I( osx)(见man page)。

答案 1 :(得分:28)

最简单的解决方案:

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

在崇高中,点击文件 - >使用编码保存 - > UTF-8

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

import pandas as pd
data = pd.read_csv('file_name.csv', encoding='utf-8')

编辑1:

如果文件很多,那么您可以跳过崇高步骤。

只需使用

阅读文件即可
data = pd.read_csv('file_name.csv', encoding='utf-8')

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

encoding = "cp1252"
encoding = "ISO-8859-1"

答案 2 :(得分:11)

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)
    
  2. 您不希望被编码问题困扰,无论某些文本字段是否包含垃圾内容,都只希望加载该死的文件。好的,您只需要使用Latin1编码,因为它接受任何可能的字节作为输入(并将其转换为相同代码的unicode字符):

    pd.read_csv(input_file_and_path, ..., encoding='latin1')
    
  3. 您知道大多数文件都是使用特定的编码编写的,但是它也包含编码错误。一个真实的示例是一个UTF8文件,该文件已使用非utf8编辑器进行了编辑,并且其中包含一些使用不同编码的行。 Pandas没有提供特殊的错误处理的准备,但是Python open函数具有(假设Python3),并且read_csv接受类似于object的文件。在这里使用的典型错误参数是'ignore',它仅抑制有问题的字节;或者(更好的IMHO)'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, ...)
    

答案 3 :(得分:6)

with open('filename.csv') as f:
   print(f)

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

data=pd.read_csv('filename.csv', encoding="encoding as you found earlier"

你去了

答案 4 :(得分:4)

请尝试添加

event

这将有所帮助。为我工作。另外,请确保使用正确的定界符和列名。

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

答案 5 :(得分:4)

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

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())

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

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

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

答案 6 :(得分:3)

尝试更改编码。 就我而言,encoding = "utf-16"有效。

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

答案 7 :(得分:1)

在我的情况下,根据Notepad ++,文件具有“ USC-2 LE BOM”编码。 对于python,它的编码为“ utf_16_le”。

希望,这有助于更快找到某人的答案。

答案 8 :(得分:1)

这个答案似乎可以解决CSV编码问题。如果您的标头出现奇怪的编码问题,如下所示:

>>> f = open(filename,"r")
>>> reader = DictReader(f)
>>> next(reader)
OrderedDict([('\ufeffid', '1'), ... ])

然后,在CSV文件的开头有一个字节顺序标记(BOM)字符。这个答案解决了这个问题:

Python read csv - BOM embedded into the first key

解决方案是使用encoding="utf-8-sig"加载CSV:

>>> f = open(filename,"r", encoding="utf-8-sig")
>>> reader = DictReader(f)
>>> next(reader)
OrderedDict([('id', '1'), ... ])

希望这对某人有帮助。

答案 9 :(得分:1)

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

df = pd.read_csv(input_file_path,...engine='python')

答案 10 :(得分:1)

挣扎了一段时间,我想我会发布这个问题,因为这是第一个搜索结果。将encoding ='iso-8859-1“标签添加到pandas read_csv不起作用,也没有任何其他编码,继续给出UnicodeDecodeError。

如果要将文件句柄传递给pd.read_csv(),则需要在文件上打开encoding =属性,而不是在read_csv中。事后看来很明显,但要追查是一个微妙的错误。

答案 11 :(得分:1)

我正在发布答案,以提供有关为什么会出现此问题的更新解决方案和解释。假设您正在从数据库或Excel工作簿中获取此数据。如果您有特殊字符,例如La Cañada Flintridge city,除非您使用UTF-8编码导出数据,否则将引入错误。 La Cañada Flintridge city将成为La Ca\xf1ada Flintridge city。如果您使用pandas.read_csv而不对默认参数进行任何调整,则会遇到以下错误

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in position 5: invalid continuation byte

幸运的是,有一些解决方案。

选项1 ,修复导出问题。确保使用UTF-8编码。

选项2 ,如果您无法解决出口问题,并且需要使用pandas.read_csv,请确保包括以下参数engine='python'。默认情况下,pandas使用engine='C',它非常适合读取大型干净文件,但是如果出现意外情况,它将崩溃。以我的经验,设置encoding='utf-8'从未修复此UnicodeDecodeError。另外,您不需要使用errors_bad_lines,但是,如果您真的需要它,这仍然是一个选择。

pd.read_csv(<your file>, engine='python')

选项3:解决方案是我个人首选的解决方案。使用香草Python读取文件。

import pandas as pd

data = []

with open(<your file>, "rb") as myfile:
    # read the header seperately
    # decode it as 'utf-8', remove any special characters, and split it on the comma (or deliminator)
    header = myfile.readline().decode('utf-8').replace('\r\n', '').split(',')
    # read the rest of the data
    for line in myfile:
        row = line.decode('utf-8', errors='ignore').replace('\r\n', '').split(',')
        data.append(row)

# save the data as a dataframe
df = pd.DataFrame(data=data, columns = header)

希望这可以帮助人们第一次遇到此问题。

答案 12 :(得分:1)

您可以尝试一下。

import csv
import pandas as pd
df = pd.read_csv(filepath,encoding='unicode_escape')

答案 13 :(得分:1)

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

_values = pd.read_csv("C:\Users\Mujeeb\Desktop\file.xlxs")

^此行导致相同的错误,因为我正在使用read_csv()方法读取Excel文件。使用read_excel()来读取.xlxs

答案 14 :(得分:0)

有时问题仅在于.csv文件。该文件可能已损坏。 遇到这个问题的时候。再次将文件另存为csv。

0. Open the xls/csv file
1. Go to -> files 
2. Click -> Save As 
3. Write the file name 
4. Choose 'file type' as -> CSV [very important]
5. Click -> Ok 

答案 15 :(得分:0)

您可以尝试:

df = pd.read_csv('./file_name.csv', encoding='gbk')

答案 16 :(得分:0)

Pandas 不会通过更改编码样式来自动替换有问题的字节。就我而言,将编码参数从 encoding = "utf-8" 更改为 encoding = "utf-16" 解决了该问题。

答案 17 :(得分:0)

我无法打开从网上银行下载的简体中文CSV文件, 我尝试过latin1,我尝试过iso-8859-1,我尝试过cp1252,但无济于事。

但是 pd.read_csv("",encoding ='gbk') 只是完成工作。

答案 18 :(得分:0)

在传递给熊猫之前,请检查编码。它将使您减速,但是...

with open(path, 'r') as f:
    encoding = f.encoding 

df = pd.read_csv(path,sep=sep, encoding=encoding)

在python 3.7中

答案 19 :(得分:0)

尝试一下:

import pandas as pd
with open('filename.csv') as f:
    data = pd.read_csv(f)

看起来它会处理编码,而无需通过参数明确表示

答案 20 :(得分:0)

就我而言,这适用于python 2.7:

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

并且仅对于python 3:

data = read_csv(filename, encoding = "ISO-8859-1", low_memory=False) 

答案 21 :(得分:0)

我正在使用Jupyter笔记本。以我为例,它以错误的格式显示文件。 “编码”选项无效。 因此,我将CSV保存为utf-8格式,并且可以正常工作。

答案 22 :(得分:0)

我正在发布对此旧线程的更新。我找到了一个可行的解决方案,但需要打开每个文件。我在LibreOffice中打开了csv文件,选择另存为>编辑过滤器设置。在下拉菜单中,我选择了UTF8编码。然后我将encoding="utf-8-sig"添加到了data = pd.read_csv(r'C:\fullpathtofile\filename.csv', sep = ',', encoding="utf-8-sig")

希望这对某人有帮助。