589

I'm running a program which is processing 30,000 similar files. A random number of them are stopping and producing this error...

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

The source/creation of these files all come from the same place. What's the best way to correct this to proceed with the import?

4

25 回答 25

1072

read_csv可以encoding选择处理不同格式的文件。我主要使用read_csv('file', encoding = "ISO-8859-1"), 或者encoding = "utf-8"用于阅读,通常utf-8用于to_csv.

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

请参阅相关的 Pandas 文档csv 文件上的 python 文档示例,以及关于 SO 的大量相关问题。一个好的背景资源是每个开发人员都应该知道的关于 unicode 和字符集的知识。

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

于 2013-08-11T13:10:22.297 回答
180

最简单的解决方案:

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

替代解决方案:

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

在 sublime 中,点击 File -> Save with encoding -> UTF-8

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

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

其他不同的编码类型是:

encoding = "cp1252"
encoding = "ISO-8859-1"
于 2017-12-21T09:53:58.747 回答
33

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 没有提供特殊的错误处理,但 Pythonopen函数有(假设是 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, ...)
    
于 2018-08-09T09:42:15.027 回答
21
with open('filename.csv') as f:
   print(f)

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

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

你去吧

于 2018-12-15T13:49:32.597 回答
12

This is a more general script approach for the stated question.

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

One starts with all the standard encodings available for the python version (in this case 3.7 python 3.7 standard encodings). A usable python list of the standard encodings for the different python version is provided here: Helpful Stack overflow answer

Trying each encoding on a small chunk of the data; only printing the working encoding. The output is directly obvious. This output also addresses the problem that an encoding like 'latin1' that runs through with ought any error, does not necessarily produce the wanted outcome.

In case of the question, I would try this approach specific for problematic CSV file and then maybe try to use the found working encoding for all others.

于 2021-02-05T12:04:35.223 回答
8

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

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

于 2018-12-18T06:13:17.290 回答
8

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

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

于 2020-07-07T16:45:26.057 回答
7

请尝试添加

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

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

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

于 2020-05-21T05:39:51.037 回答
6

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

df = pd.read_csv(input_file_path,...engine='python')
于 2019-01-31T02:52:12.743 回答
5

就我而言,这适用于 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) 
于 2019-07-26T15:49:38.953 回答
4

我发布了一个答案,以提供更新的解决方案并解释为什么会出现此问题。假设您从数据库或 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:解决方案是我个人的首选解决方案。使用 vanilla 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)

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

于 2019-10-22T17:12:38.913 回答
4

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

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

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

于 2020-04-21T20:36:21.293 回答
4

你可以试试这个。

import csv
import pandas as pd
df = pd.read_csv(filepath,encoding='unicode_escape')
于 2020-06-14T09:33:29.297 回答
4

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

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

于 2018-05-13T17:12:35.980 回答
3

我在打开从网上银行下载的简体中文 CSV 文件时遇到问题,我试过了latin1,我试过了iso-8859-1,我试过cp1252了,都无济于事。

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

于 2019-11-03T06:01:07.467 回答
2

这个答案似乎是 CSV 编码问题的全部。如果您的标头出现奇怪的编码问题,如下所示:

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

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

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

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

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

希望这可以帮助某人。

于 2018-12-17T18:14:28.503 回答
2

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

希望这可以帮助某人。

于 2019-01-01T00:54:23.283 回答
2

在传递给 pandas 之前检查编码。它会减慢你的速度,但是...

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

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

在蟒蛇 3.7

于 2019-10-11T14:12:16.790 回答
1

我正在使用 Jupyter 笔记本。就我而言,它以错误的格式显示文件。“编码”选项不起作用。所以我将 csv 保存为 utf-8 格式,它可以工作。

于 2019-05-13T00:18:17.957 回答
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 
于 2020-10-03T17:17:27.770 回答
0

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

于 2021-05-26T20:59:48.520 回答
0

您可以尝试:

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

于 2020-07-07T09:44:37.377 回答
0

您始终可以尝试先使用 chardet 或 cchardet 检测文件的编码:

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)

于 2022-03-02T06:50:38.343 回答
0

尝试这个:

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

看起来它会处理编码而不通过参数明确表达它

于 2019-10-08T04:32:57.000 回答
0

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

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

pd.read_csv(open(filename, 'r'), delimiter=';')

一切似乎都很好。

于 2021-12-28T08:26:37.350 回答