关于csv:Python Pandas错误标记数据

Python Pandas Error tokenizing data

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

pandas.parser.CParserError: Error tokenizing data. C error: Expected 2 fields in line 3, saw 12

我曾尝试阅读熊猫文档,但一无所获。

我的代码很简单:

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

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

档案来自晨星


你也可以试试;

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

请注意,这将导致跳过违规行。


这可能是一个问题

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

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

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

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

根据文档,分隔符应该不是问题。文档说"如果sep为None [未指定],将尝试自动确定这个。"然而,我对此并没有好运,包括具有明显分隔符的实例。


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

尝试使用data = pd.read_csv(path, skiprows=2)


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

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

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


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

1
data=pd.read_csv("File_path", sep='\t')


我也有这个问题,但也许是出于其他原因。我的CSV中有一些尾随逗号,它们添加了一个pandas试图阅读的附加列。使用以下工作,但它只是忽略坏线:

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

如果你想保持线条是一种丑陋的黑客来处理错误就是做如下的事情:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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阅读器就可以避免这一切。希望大熊猫开发人员能够在未来更轻松地处理这种情况。


我自己有几次这个问题。几乎每次,原因是我试图打开的文件不是一个正确保存的CSV开始。并且通过"正确",我的意思是每行具有相同数量的分隔符或列。

通常它发生是因为我在Excel中打开了CSV然后不正确地保存了它。即使文件扩展名仍为.csv,纯CSV格式也已更改。

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

希望有所帮助。


我有这个问题,我试图用CSV读取而不传递列名。

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

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

1
2
col_names = ["col1","col2","col3", ...]
df = pd.read_csv(filename, names=col_names)

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

编辑:
当您在文件中有一些文本与实际数据格式不同时,我发现此错误会逐渐增加。这通常是页眉或页脚信息(大于一行,因此skip_header不起作用),它们不会被与实际数据相同数量的逗号分隔(使用read_csv时)。使用read_table使用选项卡作为分隔符,可以绕过用户当前错误但引入其他错误。

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

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


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

1
2
3
4
5
6
7
8
9
10
11
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会改变任何东西

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

Segmentation fault (core dumped)

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

1
2
3
4
5
6
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 '"'

很明显,大熊猫在解析我们的行时遇到了问题。要使用python引擎解析表,我需要事先从表中删除所有空格和引号。与此同时,C引擎即使用逗号连续排列也一直在崩溃。

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

1
2
3
4
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;博士

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


在参数中使用分隔符

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

它会读。


以下命令序列工作(我丢失数据的第一行-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']

以下不起作用:

<5233>

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

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

CParserError:标记数据时出错。 C错误:预计行1605634中的53个字段,见54

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


虽然不是这个问题的情况,但压缩数据也可能出现此错误。显式设置kwarg compression的值解决了我的问题。

1
result = pandas.read_csv(data_source, compression='gzip')

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

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

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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模块对于格式不佳的逗号分隔文件来说更加健壮,所以这条路线成功地解决了这些问题。


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

1
quoting=3 # 3 correlates to csv.QUOTE_NONE for pandas


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

当试图从链接中读取csv数据时

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

我将网站中的数据复制到我的csvfile中。它有额外的空间所以使用sep =','它工作:)


我有类似的情况和设置

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

工作


read_csv时遇到同样的问题:ParserError:错误标记数据。
我刚刚将旧的csv文件保存到新的csv文件中。问题已经解决了!


以下是我的工作(我发布了这个答案,因为我特意在Google Colaboratory笔记本中遇到了这个问题):

1
df = pd.read_csv("/path/foo.csv", delimiter=';', skiprows=0, low_memory=False)


这就是我做的。

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

1
2
data=pd.read_csv('C:\\Users\\HP\\Downloads\
PL ASSINGMENT 2 imdb_labelled\\imdb_labelled.txt'
,engine='python',header=None,sep='::')

我有一个包含现有行号的数据集,我使用了index_col:

1
pd.read_csv('train.csv', index_col=0)

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


对我来说问题是我的CSV日内附加了一个新列。如果我使用error_bad_lines=False,接受的答案解决方案将无效,因为每个未来的行都将被丢弃。

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

1
2
3
4
5
6
7
8
9
10
11
12
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.

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

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


我用错误的引号遇到了这个错误。我使用映射软件,在导出逗号分隔文件时会在文本项周围加上引号。使用引号的文本(例如'= feet和"=英寸)可能会有问题。请考虑这个例子,它注意到5英寸的井日志打印很差:

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

使用5"作为5 inch的简写,最终会在工作中抛出一把扳手。 Excel将简单地剥离额外的引号,但是Pandas在没有上面提到的error_bad_lines=False参数的情况下会崩溃。


我用错误的引号遇到了这个错误。我使用映射软件,在导出逗号分隔文件时会在文本项周围加上引号。使用引号的文本(例如'= feet和"=英寸)可能会有问题。请考虑这个例子,它注意到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 ++)执行查找替换可能是最容易的。


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


问题可能出在文件问题上,在我的情况下,问题在重命名文件后得到解决。还没弄清楚原因..


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

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

只需添加 - header=None

希望这可以帮助!!


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


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