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) |
我该如何解决这个问题? 我应该使用
档案来自晨星
你也可以试试;
1 | data = pd.read_csv('file1.csv', error_bad_lines=False) |
请注意,这将导致跳过违规行。
这可能是一个问题
- 数据中的分隔符
- 第一行,正如@TomAugspurger所说
要解决此问题,请在调用
1 | df = pandas.read_csv(fileName, sep='delimiter', header=None) |
在上面的代码中,
根据文档,分隔符应该不是问题。文档说"如果sep为None [未指定],将尝试自动确定这个。"然而,我对此并没有好运,包括具有明显分隔符的实例。
解析器被文件的标题弄糊涂了。它读取第一行并推断该行的列数。但前两行不代表文件中的实际数据。
尝试使用
您的CSV文件可能具有可变数量的列,
1)将CSV文件更改为具有最大列数的虚拟第一行(并指定
2)或使用
这绝对是分隔符的问题,因为大多数csv 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) |
我事先在列表中指定了列名,然后将它们传递给
1 2 | col_names = ["col1","col2","col3", ...] df = pd.read_csv(filename, names=col_names) |
我遇到了同样的问题。在同一源文件上使用
编辑:
当您在文件中有一些文本与实际数据格式不同时,我发现此错误会逐渐增加。这通常是页眉或页脚信息(大于一行,因此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-,但至少它加载):
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
以下不起作用:
header=None)
CParserError:标记数据时出错。 C错误:预计行1605634中的53个字段,见54
因此,在您的问题中,您必须传递
虽然不是这个问题的情况,但压缩数据也可能出现此错误。显式设置
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模块对于格式不佳的逗号分隔文件来说更加健壮,所以这条路线成功地解决了这些问题。
我使用的数据集有很多引号(")使用了无关的格式。我能够通过包含
1 | quoting=3 # 3 correlates to csv.QUOTE_NONE for pandas |
使用
当试图从链接中读取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) |
这就是我做的。
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日内附加了一个新列。如果我使用
在这种情况下的解决方案是使用
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英寸的井日志打印很差:
US42051316890000,30.4386484,-96.4330734,"poor 5""
使用
我用错误的引号遇到了这个错误。我使用映射软件,在导出逗号分隔文件时会在文本项周围加上引号。使用引号的文本(例如'= feet和"=英寸)可能会有问题。请考虑这个例子,它注意到5英寸的井日志打印很差:
US42051316890000,30.4386484,-96.4330734,"poor 5""
使用
一旦知道错误的性质,在导入之前从文本编辑器(例如,Sublime Text 3或Notepad ++)执行查找替换可能是最容易的。
已经提到了大多数有用的答案,但我建议将pandas数据帧保存为镶木地板文件。 Parquet文件没有这个问题,它们同时具有内存效率。
问题可能出在文件问题上,在我的情况下,问题在重命名文件后得到解决。还没弄清楚原因..
您可以执行此步骤以避免此问题 -
1 | train = pd.read_csv('/home/Project/output.csv' , header=None) |
只需添加 -
希望这可以帮助!!
我从同事处收到了.csv,当我尝试使用pd.read_csv()读取csv时,我收到了类似的错误。它显然试图使用第一行来生成数据帧的列,但是有许多行包含的列比第一行所暗示的要多。我最后通过打开并将文件重新保存为.csv并再次使用pd.read_csv()来解决此问题。
尝试: