532

我正在尝试使用 pandas 来操作 .csv 文件,但出现此错误:

pandas.parser.CParserError:错误标记数据。C 错误:预计第 3 行中有 2 个字段,看到 12

我试图阅读 pandas 文档,但一无所获。

我的代码很简单:

path = 'GOOG Key Ratios.csv'
#print(open(path).read())
data = pd.read_csv(path)

我该如何解决这个问题?我应该使用csv模块还是其他语言?

文件来自晨星

4

43 回答 43

804

你也可以试试;

data = pd.read_csv('file1.csv', on_bad_lines='skip')

请注意,这将导致有问题的行被跳过。

于 2013-08-08T14:47:15.083 回答
165

这可能是一个问题

  • 数据中的分隔符
  • 第一行,正如@TomAugspurger 所说

要解决它,请尝试在调用时指定sep和/或header参数read_csv。例如,

df = pandas.read_csv(filepath, sep='delimiter', header=None)

在上面的代码中,sep定义您的分隔符并header=None告诉 pandas 您的源数据没有标题/列标题行。因此,文档说:“如果文件不包含标题行,那么您应该明确传递 header=None”。在这种情况下,pandas 会自动为每个字段 {0,1,2,...} 创建整数索引。

根据文档,分隔符应该不是问题。文档说“如果 sep 是 None [未指定],将尝试自动确定这一点。” 但是,我对此并不好运,包括带有明显分隔符的实例。

另一种解决方案可能是尝试自动检测分隔符

# use the first 2 lines of the file to detect separator
temp_lines = csv_file.readline() + '\n' + csv_file.readline()
dialect = csv.Sniffer().sniff(temp_lines, delimiters=';,')

# remember to go back to the start of the file for the next time it's read
csv_file.seek(0) 

df = pd.read_csv(csv_file, sep=dialect.delimiter)

于 2014-10-28T02:18:23.647 回答
57

解析器被文件头弄糊涂了。它读取第一行并从该行推断列数。但前两行并不代表文件中的实际数据。

试试看data = pd.read_csv(path, skiprows=2)

于 2013-08-04T02:24:35.393 回答
48

这绝对是分隔符的问题,因为大多数 csv CSV 都是使用创建的,sep='/t'因此请尝试使用分隔符来read_csv使用制表符。因此,尝试使用以下代码行打开。(\t)/t

data=pd.read_csv("File_path", sep='\t')
于 2015-04-01T05:42:48.260 回答
38

您的 CSV 文件可能具有可变数量的列,并read_csv从前几行推断出列数。在这种情况下有两种解决方法:

1) 将 CSV 文件更改为具有最大列数的虚拟第一行(并指定header=[0]

2) 或者使用names = list(range(0,N))其中 N 是最大列数。

于 2017-03-31T16:29:00.857 回答
36

我遇到了这个问题,我试图在不传入列名的情况下读取 CSV。

df = pd.read_csv(filename, header=None)

我事先在列表中指定了列名,然后将它们传递给names,它立即解决了它。如果您没有设置列名,则可以创建与数据中可能包含的最大列数一样多的占位符名称。

col_names = ["col1", "col2", "col3", ...]
df = pd.read_csv(filename, names=col_names)
于 2019-01-08T18:57:22.093 回答
23

我也有这个问题,但可能是出于不同的原因。我的 CSV 中有一些尾随逗号,它们添加了 pandas 试图读取的附加列。使用以下作品,但它只是忽略了坏行:

data = pd.read_csv('file1.csv', error_bad_lines=False)

如果您想让这些行保持一种丑陋的 hack 来处理错误,请执行以下操作:

line     = []
expected = []
saw      = []     
cont     = True 

while cont == True:     
    try:
        data = pd.read_csv('file1.csv',skiprows=line)
        cont = False
    except Exception as e:    
        errortype = e.message.split('.')[0].strip()                                
        if errortype == 'Error tokenizing data':                        
           cerror      = e.message.split(':')[1].strip().replace(',','')
           nums        = [n for n in cerror.split(' ') if str.isdigit(n)]
           expected.append(int(nums[0]))
           saw.append(int(nums[2]))
           line.append(int(nums[1])-1)
         else:
           cerror      = 'Unknown'
           print 'Unknown Error - 222'

if line != []:
    # Handle the errors however you want

我继续编写一个脚本来将这些行重新插入到 DataFrame 中,因为坏行将由上述代码中的变量 'line' 给出。这一切都可以通过简单地使用 csv 阅读器来避免。希望 pandas 开发人员将来可以更轻松地处理这种情况。

于 2016-02-04T22:16:44.623 回答
15

以下内容对我有用(我发布了这个答案,因为我在 Google Colaboratory Notebook 中特别遇到了这个问题):

df = pd.read_csv("/path/foo.csv", delimiter=';', skiprows=0, low_memory=False)
于 2019-08-20T09:37:20.953 回答
13

你可以试试;

data = pd.read_csv('file1.csv', sep='\t')
于 2020-09-08T15:58:01.873 回答
12

我遇到了同样的问题。在同一个源文件上使用pd.read_table()似乎有效。我无法追查其原因,但它对我的案例来说是一个有用的解决方法。也许更有知识的人可以更清楚地说明它为什么起作用。

编辑:我发现当您的文件中有一些文本与实际数据的格式不同时,这个错误就会出现。这通常是页眉或页脚信息(多于一行,因此 skip_header 不起作用),不会被与实际数据相同数量的逗号分隔(使用 read_csv 时)。使用 read_table 使用制表符作为分隔符,可以规避用户当前的错误,但会引入其他错误。

我通常通过将额外数据读入文件然后使用 read_csv() 方法来解决这个问题。

确切的解决方案可能会因您的实际文件而异,但这种方法在几种情况下对我有用

于 2014-06-30T11:46:21.983 回答
12

我自己也遇到过几次这个问题。几乎每次,原因是我试图打开的文件一开始就不是正确保存的 CSV。“正确地”是指每一行都有相同数量的分隔符或列。

通常发生这种情况是因为我在 Excel 中打开了 CSV,然后不正确地保存了它。尽管文件扩展名仍然是 .csv,但纯 CSV 格式已被更改。

使用 pandas to_csv 保存的任何文件都将被正确格式化并且不应该有这个问题。但是如果你用另一个程序打开它,它可能会改变结构。

希望有帮助。

于 2016-07-07T17:22:00.377 回答
7

我在尝试读取带有空格、逗号和引号的制表符分隔表时遇到了类似的问题:

1115794 4218    "k__Bacteria", "p__Firmicutes", "c__Bacilli", "o__Bacillales", "f__Bacillaceae", ""
1144102 3180    "k__Bacteria", "p__Firmicutes", "c__Bacilli", "o__Bacillales", "f__Bacillaceae", "g__Bacillus", ""
368444  2328    "k__Bacteria", "p__Bacteroidetes", "c__Bacteroidia", "o__Bacteroidales", "f__Bacteroidaceae", "g__Bacteroides", ""



import pandas as pd
# Same error for read_table
counts = pd.read_csv(path_counts, sep='\t', index_col=2, header=None, engine = 'c')

pandas.io.common.CParserError: Error tokenizing data. C error: out of memory

这表示它与 C 解析引擎(这是默认引擎)有关。也许换成 python 会改变任何事情

counts = pd.read_table(path_counts, sep='\t', index_col=2, header=None, engine='python')

Segmentation fault (core dumped)

现在这是一个不同的错误。
如果我们继续尝试从表中删除空格,python-engine 的错误将再次发生变化:

1115794 4218    "k__Bacteria","p__Firmicutes","c__Bacilli","o__Bacillales","f__Bacillaceae",""
1144102 3180    "k__Bacteria","p__Firmicutes","c__Bacilli","o__Bacillales","f__Bacillaceae","g__Bacillus",""
368444  2328    "k__Bacteria","p__Bacteroidetes","c__Bacteroidia","o__Bacteroidales","f__Bacteroidaceae","g__Bacteroides",""


_csv.Error: '   ' expected after '"'

很明显,pandas 在解析我们的行时遇到了问题。要使用 python 引擎解析表,我需要事先从表中删除所有空格和引号。同时,即使逗号成行,C 引擎也会不断崩溃。

为了避免创建带有替换的新文件,我这样做了,因为我的表很小:

from io import StringIO
with open(path_counts) as f:
    input = StringIO(f.read().replace('", ""', '').replace('"', '').replace(', ', ',').replace('\0',''))
    counts = pd.read_table(input, sep='\t', index_col=2, header=None, engine='python')

tl;dr
更改解析引擎,尽量避免数据中的任何非分隔引号/逗号/空格。

于 2017-04-24T11:28:41.473 回答
7

我使用的数据集有很多引号 (") 使用了与格式无关的格式。我能够通过包含以下参数来修复错误read_csv()

quoting=3 # 3 correlates to csv.QUOTE_NONE for pandas
于 2019-06-26T19:09:22.377 回答
6

在参数中使用分隔符

pd.read_csv(filename, delimiter=",", encoding='utf-8')

它会读。

于 2018-11-21T13:03:24.263 回答
5

对于那些在 Linux 操作系统上遇到 Python 3 类似问题的人。

pandas.errors.ParserError: Error tokenizing data. C error: Calling
read(nbytes) on source failed. Try engine='python'.

尝试:

df.read_csv('file.csv', encoding='utf8', engine='python')
于 2019-10-14T14:54:07.707 回答
4

在我的情况下,分隔符不是默认的“,”而是 Tab。

pd.read_csv(file_name.csv, sep='\\t',lineterminator='\\r', engine='python', header='infer')

注意:“\t”没有按照某些来源的建议工作。"\\t" 是必需的。

于 2020-05-04T18:27:09.893 回答
4

尽管此问题不是这种情况,但压缩数据也可能出现此错误。明确设置kwarg compression解决我的问题的值。

result = pandas.read_csv(data_source, compression='gzip')
于 2016-10-03T15:45:19.487 回答
3

据我所知,在查看您的文件后,问题是您尝试加载的 csv 文件有多个表。有空行或包含表格标题的行。尝试看看这个Stackoverflow 答案。它展示了如何以编程方式实现这一目标。

另一种动态方法是使用csv 模块,一次读取每一行并进行完整性检查/正则表达式,以推断该行是否为(标题/标题/值/空白)。这种方法还有一个优势,您可以根据需要在 python 对象中拆分/附加/收集数据。

pd.read_clipboard()最简单的方法是在手动选择表格并将其复制到剪贴板后使用 pandas 功能,以防您可以在 excel 中打开 csv 或其他东西。

无关

此外,与您的问题无关,但因为没有人提到这一点:我在加载一些数据集(例如seeds_dataset.txt来自 UCI)时遇到了同样的问题。就我而言,发生错误是因为某些分隔符的空格比真正的 tab 更多\t。例如,请参见下面的第 3 行

14.38   14.21   0.8951  5.386   3.312   2.462   4.956   1
14.69   14.49   0.8799  5.563   3.259   3.586   5.219   1
14.11   14.1    0.8911  5.42    3.302   2.7     5       1

因此,\t+在分隔符模式中使用而不是\t.

data = pd.read_csv(path, sep='\t+`, header=None)
于 2019-11-03T09:35:50.653 回答
3

以下命令序列有效(我丢失了数据的第一行 -no header=None present-,但至少它加载了):

df = pd.read_csv(filename, usecols=range(0, 42)) df.columns = ['YR', 'MO', 'DAY', 'HR', 'MIN', 'SEC', 'HUND', 'ERROR', 'RECTYPE', 'LANE', 'SPEED', 'CLASS', 'LENGTH', 'GVW', 'ESAL', 'W1', 'S1', 'W2', 'S2', 'W3', 'S3', 'W4', 'S4', 'W5', 'S5', 'W6', 'S6', 'W7', 'S7', 'W8', 'S8', 'W9', 'S9', 'W10', 'S10', 'W11', 'S11', 'W12', 'S12', 'W13', 'S13', 'W14']

以下不起作用:

df = pd.read_csv(filename, names=['YR', 'MO', 'DAY', 'HR', 'MIN', 'SEC', 'HUND', 'ERROR', 'RECTYPE', 'LANE', 'SPEED', 'CLASS', 'LENGTH', 'GVW', 'ESAL', 'W1', 'S1', 'W2', 'S2', 'W3', 'S3', 'W4', 'S4', 'W5', 'S5', 'W6', 'S6', 'W7', 'S7', 'W8', 'S8', 'W9', 'S9', 'W10', 'S10', 'W11', 'S11', 'W12', 'S12', 'W13', 'S13', 'W14'], usecols=range(0, 42))

CParserError:标记数据时出错。C 错误:预计第 1605634 行中的 53 个字段,看到 54 以下不起作用:

df = pd.read_csv(filename, header=None)

CParserError:标记数据时出错。C 错误:预计第 1605634 行中有 53 个字段,看到 54

因此,在您的问题中,您必须通过usecols=range(0, 2)

于 2018-05-23T11:45:25.387 回答
3

有时问题不在于如何使用 python,而在于原始数据。
我收到此错误消息

Error tokenizing data. C error: Expected 18 fields in line 72, saw 19.

原来,在列描述中有时会有逗号。这意味着需要清理 CSV 文件或使用其他分隔符。

于 2017-11-15T10:59:33.123 回答
3

我相信解决方案,

,engine='python'
, error_bad_lines = False

如果它是虚拟列并且您想删除它会很好。在我的例子中,第二行确实有更多的列,我希望这些列被集成并且列数 = MAX(列)。

请参考以下我无法在任何地方阅读的解决方案:

try:
    df_data = pd.read_csv(PATH, header = bl_header, sep = str_sep)
except pd.errors.ParserError as err:
    str_find = 'saw '
    int_position = int(str(err).find(str_find)) + len(str_find)
    str_nbCol = str(err)[int_position:]
    l_col = range(int(str_nbCol))
    df_data = pd.read_csv(PATH, header = bl_header, sep = str_sep, names = l_col)
于 2020-05-13T06:41:07.080 回答
3

我发现在处理类似的解析错误时有用的替代方法是使用 CSV 模块将数据重新路由到 pandas df。例如:

import csv
import pandas as pd
path = 'C:/FileLocation/'
file = 'filename.csv'
f = open(path+file,'rt')
reader = csv.reader(f)

#once contents are available, I then put them in a list
csv_list = []
for l in reader:
    csv_list.append(l)
f.close()
#now pandas has no problem getting into a df
df = pd.DataFrame(csv_list)

我发现 CSV 模块对于格式不佳的逗号分隔文件更加健壮,因此通过这条路线成功解决了此类问题。

于 2018-01-26T20:54:38.047 回答
2

我遇到了这个问题的多种解决方案。很多人也对答案给出了最好的解释。但对于初学者来说,我认为以下两种方法就足够了:

import pandas as pd

#Method 1

data = pd.read_csv('file1.csv', error_bad_lines=False)
#Note that this will cause the offending lines to be skipped.

#Method 2 using sep

data = pd.read_csv('file1.csv', sep='\t')
于 2021-12-14T06:25:23.473 回答
2

简单的解决方法:在 excel 中打开 csv 文件并使用不同名称的 csv 格式文件保存。再次尝试导入 spyder,您的问题将得到解决!

于 2019-09-07T01:53:53.223 回答
2

利用 pandas.read_csv('CSVFILENAME',header=None,sep=', ')

尝试从链接读取 csv 数据时

http://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data

我将网站上的数据复制到了我的 csvfile 中。它有额外的空格,所以使用了 sep =', ' 并且它起作用了:)

于 2018-01-02T09:56:48.143 回答
2

我有一个类似的情况和设置

train = pd.read_csv('input.csv' , encoding='latin1',engine='python') 

工作过

于 2018-11-20T02:08:07.247 回答
2

标记数据时出错。C 错误:预计第 3 行中有 2 个字段,看到 12

该错误为解决“第 3 行中的预期 2 个字段,锯 12”问题提供了线索,锯 12 表示第二行的长度为 12,第一行的长度为 2。

当您有如下所示的数据时,如果您跳过行,那么大部分数据将被跳过

data = """1,2,3
1,2,3,4
1,2,3,4,5
1,2
1,2,3,4"""

如果您不想跳过任何行,请执行以下操作

#First lets find the maximum column for all the rows
with open("file_name.csv", 'r') as temp_f:
    # get No of columns in each line
    col_count = [ len(l.split(",")) for l in temp_f.readlines() ]

### Generate column names  (names will be 0, 1, 2, ..., maximum columns - 1)
column_names = [i for i in range(max(col_count))] 

import pandas as pd
# inside range set the maximum value you can see in "Expected 4 fields in line 2, saw 8"
# here will be 8 
data = pd.read_csv("file_name.csv",header = None,names=column_names )

使用范围而不是手动设置名称,因为当您有很多列时会很麻烦。

此外,如果您需要使用偶数数据长度,您可以用 0 填充 NaN 值。例如。用于聚类(k-means)

new_data = data.fillna(0)
于 2020-02-16T09:58:45.673 回答
1

这就是我所做的。

sep='::'解决了我的问题:

data=pd.read_csv('C:\\Users\\HP\\Downloads\\NPL ASSINGMENT 2 imdb_labelled\\imdb_labelled.txt',engine='python',header=None,sep='::')
于 2018-10-21T13:04:24.810 回答
1

在我的情况下,这是因为csv文件的第一行和最后两行的格式与文件的中间内容不同。

所以我所做的就是将 csv 文件作为字符串打开,解析字符串的内容,然后用于read_csv获取数据帧。

import io
import pandas as pd

file = open(f'{file_path}/{file_name}', 'r')
content = file.read()

# change new line character from '\r\n' to '\n'
lines = content.replace('\r', '').split('\n')

# Remove the first and last 2 lines of the file
# StringIO can be considered as a file stored in memory
df = pd.read_csv(StringIO("\n".join(lines[2:-2])), header=None)
于 2019-11-27T01:13:44.967 回答
1

对我来说,问题是我的 CSV盘中附加了一个新列。接受的答案解决方案将不起作用,因为如果我使用error_bad_lines=False.

在这种情况下,解决方案pd.read_csv(). 这样,我可以只指定我需要读入 CSV 的列,并且我的 Python 代码将保持对未来 CSV 更改的弹性,只要标题列存在(并且列名不会更改)。

usecols : list-like or callable, optional 

Return a subset of the columns. If list-like, all elements must either
be positional (i.e. integer indices into the document columns) or
strings that correspond to column names provided either by the user in
names or inferred from the document header row(s). For example, a
valid list-like usecols parameter would be [0, 1, 2] or ['foo', 'bar',
'baz']. Element order is ignored, so usecols=[0, 1] is the same as [1,
0]. To instantiate a DataFrame from data with element order preserved
use pd.read_csv(data, usecols=['foo', 'bar'])[['foo', 'bar']] for
columns in ['foo', 'bar'] order or pd.read_csv(data, usecols=['foo',
'bar'])[['bar', 'foo']] for ['bar', 'foo'] order.

例子

my_columns = ['foo', 'bar', 'bob']
df = pd.read_csv(file_path, usecols=my_columns)

这样做的另一个好处是,如果我只使用具有 18-20 列的 CSV 的 3-4 列,我可以将更少的数据加载到内存中。

于 2019-03-01T14:19:06.323 回答
1

我在 read_csv: ParserError: Error tokenizing data 时遇到了同样的问题。我刚刚将旧的 csv 文件保存到一个新的 csv 文件中。问题已经解决了!

于 2018-11-26T13:32:41.587 回答
1

有时在单元格中有一个逗号“,”。由于熊猫无法阅读它。尝试用“;”分隔

df = pd.read_csv(r'yourpath', delimiter=";")
于 2021-06-01T14:51:53.893 回答
1

问题在于分隔符。找出你的数据中使用了什么样的分隔符,并像下面这样指定它:

data = pd.read_csv('some_data.csv', sep='\t')
于 2021-11-10T07:02:09.413 回答
1

我遇到了这个带有杂散引号的错误。我使用映射软件,它会在导出以逗号分隔的文件时在文本项周围加上引号。使用引号(例如 ' = 英尺和 " = 英寸)的文本在引发分隔符冲突时可能会出现问题。考虑这个例子,它指出 5 英寸的井日志打印效果很差:

UWI_key,Latitude,Longitude,Remark US42051316890000,30.4386484,-96.4330734,"poor 5""

使用5"作为5 inch最终在工作中扔扳手的简写。Excel 会简单地去掉多余的引号,但 Pandas 会在没有上述error_bad_lines=False参数的情况下崩溃。

于 2019-04-30T02:14:28.867 回答
1

我有一个带有预先存在的行号的数据集,我使用了 index_col:

pd.read_csv('train.csv', index_col=0)
于 2017-06-20T05:28:30.800 回答
1

已经提到了大多数有用的答案,但是我建议将 pandas 数据帧保存为 parquet 文件。Parquet 文件没有这个问题,而且它们同时具有内存效率。

于 2019-06-11T09:47:59.390 回答
0

我从同事那里收到了一个 .csv,当我尝试使用 pd.read_csv() 读取 csv 时,我收到了类似的错误。它显然是在尝试使用第一行来生成数据框的列,但是有很多行包含的列比第一行所暗示的要多。我最终通过简单地打开文件并将其重新保存为 .csv 并再次使用 pd.read_csv() 来解决此问题。

于 2018-07-13T17:31:54.490 回答
0

我遇到了类似的错误,问题是我的 csv 文件中有一些转义引号,需要适当地设置 escapechar 参数。

于 2017-12-12T11:43:32.280 回答
0

问题可能与文件问题有关,就我而言,重命名文件后问题已解决。还没弄清楚原因。。

于 2018-10-28T12:46:45.460 回答
0

您可以执行此步骤来避免该问题 -

train = pd.read_csv('/home/Project/output.csv' , header=None)

只需添加 -header=None

希望这可以帮助!!

于 2018-08-19T06:59:39.087 回答
0

我遇到了这个带有杂散引号的错误。我使用映射软件,它会在导出以逗号分隔的文件时在文本项周围加上引号。使用引号的文本(例如 ' = 英尺和 " = 英寸)可能会出现问题。考虑这个例子,它指出 5 英寸的测井打印效果很差:

UWI_key,Latitude,Longitude,Remark US42051316890000,30.4386484,-96.4330734,"poor 5""

使用5"作为5 inch最终在工作中扔扳手的简写。Excel 会简单地去掉多余的引号,但 Pandas 会在没有上述error_bad_lines=False参数的情况下崩溃。

一旦您知道错误的性质,在导入之前从文本编辑器(例如,Sublime Text 3 或 Notepad++)进行查找替换可能是最简单的。

于 2019-04-30T02:20:32.597 回答
0

这看起来很难看,但你会有你的数据框

import re
path = 'GOOG Key Ratios.csv'

try:
    data = pd.read_csv(path)
except Exception as e:
    val = re.findall('tokenizing.{1,100}\s*Expected\s*(\d{1,2})\s*',str(e),re.I)
    data = pd.read_csv(path, skiprows=int(val[0])-1)
于 2021-08-26T20:17:07.670 回答
-1

尝试: pandas.read_csv(path, sep = ',' ,header=None)

于 2017-10-10T08:40:28.893 回答