在Pandas with Python中读取CSV文件时出现UnicodeDecodeError

我正在运行一个程序,它正在处理3万个类似的文件。随机数量的它们停止并产生此错误…

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

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

810016 次浏览

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

您也可以使用几个alias选项之一,如'latin''cp1252' (Windows),而不是'ISO-8859-1'(参见python文档,也为您可能遇到的许多其他编码)。

< p > # EYZ0看到, CSV文件上的Python文档示例,以及SO上的大量相关问题。关于unicode和字符集,每个开发人员都应该知道的.

是一个很好的后台资源

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

最简单的解决方案:

import pandas as pd
df = pd.read_csv('file_name.csv', engine='python')

替代解决方案:

崇高的文本:

  • 打开csv文件“Sublime文本编辑器”或“VS代码”。
  • 以utf-8格式保存。
  • 在sublime中,点击File ->保存编码->utf - 8

VS代码:

在VSCode的底部栏中,您将看到标签UTF-8。点击它。弹出窗口会打开。单击“保存编码”。现在可以为该文件选择新的编码。

然后,您可以像往常一样读取您的文件:

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

其他不同的编码类型有:

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

这个问题困扰了我一段时间,我想我应该发布这个问题,因为它是第一个搜索结果。添加encoding="iso-8859-1"标签到熊猫read_csv没有工作,任何其他编码也没有工作,一直给出UnicodeDecodeError。

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

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. You do not want to be bothered with encoding questions, and only want that damn file to load, no matter if some text fields contain garbage. Ok, you only have to use Latin1 encoding because it accept any possible byte as input (and convert it to the unicode character of same code):

    pd.read_csv(input_file_and_path, ..., encoding='latin1')
    
  3. You know that most of the file is written with a specific encoding, but it also contains encoding errors. A real world example is an UTF8 file that has been edited with a non utf8 editor and which contains some lines with a different encoding. Pandas has no provision for a special error processing, but Python open function has (assuming Python3), and read_csv accepts a file like object. Typical errors parameter to use here are 'ignore' which just suppresses the offending bytes or (IMHO better) 'backslashreplace' which replaces the offending bytes by their Python’s backslashed escape sequence:

    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, ...)
    
with open('filename.csv') as f:
print(f)

执行这段代码后,你会发现'filename.csv'的编码,然后执行如下代码

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

好了

这个答案似乎是CSV编码问题的万能答案。如果你的头文件出现了奇怪的编码问题,就像这样:

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

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

Python读取csv- BOM嵌入到第一个键

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

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

希望这能帮助到一些人。

在我的例子中,一个文件有USC-2 LE BOM编码,根据notepad++。 它是python的encoding="utf_16_le"。< / p >

希望,这能帮助别人更快地找到答案。

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

希望这能帮助到一些人。

尝试指定引擎='python'。

.它对我有效,但我仍在试图弄清楚为什么
df = pd.read_csv(input_file_path,...engine='python')

我正在使用Jupyter-notebook。在我的例子中,它以错误的格式显示文件。“编码”选项不起作用。 所以我将csv保存为utf-8格式,它可以工作

在我的例子中,这适用于python 2.7:

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

对于python3,只有:

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

试试这个:

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

看起来它会处理编码,而不会通过参数显式地表示它

在传递给熊猫之前检查编码。它会让你慢下来,但是……

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


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

在python 3.7中

我发布了一个答案,提供了一个更新的解决方案和解释,为什么这个问题会发生。假设您从数据库或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)

希望这对第一次遇到这个问题的人有所帮助。

我无法打开从网上银行下载的简体中文CSV文件。 我试过latin1,我试过iso-8859-1,我试过cp1252,都没有用

但是pd.read_csv("",encoding ='gbk')只是做了这项工作。

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

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

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

请尝试添加

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

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

为了快速加载文件,可以从只加载1000行开始。

你可以试试这个。

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

你可以试试:

# EYZ0

尝试改变编码 在我的例子中,encoding = "utf-16"工作

# EYZ0

有时问题只是.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

对于上述问题,这是一种更通用的脚本方法。

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标准编码)。 这里提供了不同python版本的标准编码的可用python列表:有用的堆栈溢出回答

在一小块数据上尝试每种编码; 只打印工作编码。 输出是非常明显的。 这个输出还解决了像'latin1'这样的编码,如果有任何错误,不一定会产生想要的结果的问题

在出现问题的情况下,我会尝试这种方法专门针对有问题的CSV文件,然后可能会尝试对所有其他文件使用找到的工作编码。

Pandas不会通过更改编码样式自动替换违规字节。在我的例子中,将编码参数从encoding = "utf-8"更改为encoding = "utf-16"解决了这个问题。

在我的案例中,我无法使用之前提供的任何方法来克服这个问题。将编码器类型更改为utf-8utf-16iso-8859-1或任何其他类型都不工作。

但我没有使用pd.read_csv(filename, delimiter=';'),而是使用;

# EYZ0

一切似乎都很顺利。

您可以尝试先检测文件的编码,使用chardetcchardetcharset-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)