标记数据错误

我试图使用熊猫操作.csv文件,但我得到这个错误:

pandas.parser.CParserError:标记数据错误。C错误:第3行有2个字段,见12

我试着读过熊猫的文件,但一无所获。

我的代码很简单:

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

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

文件来自晨星

1578837 次浏览

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

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

你也可以试试;

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

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

编辑

熊猫<1.3.0试试

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

根据pandas API参考

我也遇到过同样的问题。在同一个源文件上使用pd.read_table()似乎可以工作。我找不到原因,但对我的情况来说,这是一个有用的变通办法。也许有更博学的人能解释清楚为什么它能起作用。

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

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

具体的解决方案可能因您的实际文件而异,但这种方法在一些情况下对我来说是有效的

这可能是个问题

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

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

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)


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

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

我也有这个问题,但可能是出于不同的原因。我在我的CSV中有一些尾随逗号,添加了熊猫试图读取的额外列。使用以下方法是可行的,但它只是忽略了不好的行:

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

如果你想让代码行看起来很丑,你可以这样做:

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保存的文件都将被正确格式化,不应该有这个问题。但如果你用另一个程序打开它,它可能会改变结构。

希望这能有所帮助。

虽然这个问题并非如此,但压缩数据也可能出现此错误。显式地为kwarg compression设置值解决了我的问题。

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

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

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

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

我有一个类似的问题,而试图读取一个制表符分隔表与空格,逗号和引号:

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,博士
更改解析引擎,尽量避免在数据中使用任何非分隔性的引号/逗号/空格

我有一个已有行号的数据集,我使用index_col:

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

试一试:# EYZ0

有时候问题不在于如何使用python,而在于如何处理原始数据 我得到了这个错误信息

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

结果发现,在列描述中有时会有逗号。这意味着需要清理CSV文件或使用另一个分隔符。

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

< p >使用 # EYZ0 < / p >

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

# EYZ0

我将该网站的数据复制到我的csv文件中。它有额外的空格,所以使用sep =', '并且它工作:)

在处理类似的解析错误时,我发现另一种方法很有用,它使用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模块对于格式不佳的逗号分隔的文件更加健壮,因此已经成功地用这种方法解决了诸如此类的问题。

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

df = pd.read_csv(filename, usecols =范围(0,42)) df。列=[‘年’,‘莫’,‘天’,“人力资源”,“分”,“秒”,“猎狗”, ' 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’,“确实”、“向”、“W14”)< /代码> < / p >

以下不工作:

df = pd.read_csv(filename, 名称=[‘年’,‘莫’,‘天’,“人力资源”,“分”,“秒”,“猎狗”, ' 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 =范围(0,42)) < /代码> < / p >

CParserError:标记数据错误。C错误:在1605634行中预期有53个字段,看到54

df = pd.read_csv(filename, 头=没有) < /代码> < / p >

CParserError:标记数据错误。C错误:在1605634行中预期有53个字段,看到54

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

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

你可以这样做,以避免问题-

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

只需添加- header=None

希望这能有所帮助!!

这就是我所做的。

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

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

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

我有一个类似的情况

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

工作

在参数中使用分隔符

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

它会读。

我有同样的问题,当read_csv: ParserError:错误标记数据。 我只是把旧的csv文件保存为一个新的csv文件。问题解决了!< / p >

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

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

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

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

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

这种情况下的解决方案是在pd.read_csv()中使用usecols参数。通过这种方式,我可以只指定需要读入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列,我可以将更少的数据加载到内存中。

我遇到过这样的错误,一个丢失的引号。我使用映射软件,当导出以逗号分隔的文件时,它会在文本项周围加上引号。使用引号的文本(例如:' =英尺和' =英寸)可能会导致分隔符冲突。考虑下面这个例子,5英寸的测井曲线打印很差:

< p > <代码> UWI_key、纬度、经度、备注 US42051316890000, 30.4386484, -96.4330734,“可怜的5””< /代码> < / p >

使用5"作为5 inch的简写,最终会给工作带来麻烦。Excel会简单地去掉额外的引号,但是Pandas没有上面提到的error_bad_lines=False参数就会崩溃。

我遇到过这样的错误,一个丢失的引号。我使用映射软件,当导出以逗号分隔的文件时,它会在文本项周围加上引号。使用引号的文本(例如:“=英尺”和“=英寸”)可能会有问题。考虑下面这个例子,5英寸的测井曲线打印很差:

< p > <代码> UWI_key、纬度、经度、备注 US42051316890000, 30.4386484, -96.4330734,“可怜的5””< /代码> < / p >

使用5"作为5 inch的简写,最终会给工作带来麻烦。Excel会简单地去掉额外的引号,但是Pandas没有上面提到的error_bad_lines=False参数就会崩溃。

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

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

我使用的数据集有很多引号(")使用无关的格式。我可以通过为read_csv()添加这个参数来修复这个错误:

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

以下是对我有用的(我张贴了这个答案,因为我在谷歌协作笔记本中特别遇到了这个问题):

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

简单的解决方案:在excel &中打开csv文件以CSV格式的不同名称文件保存。再次尝试导入它spyder,你的问题将得到解决!

对于那些在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')

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

另一种动态方法是使用csv模块,一次读取每一行,并进行健全检查/正则表达式,以推断该行是否为(title/header/values/blank)。使用这种方法还有一个优点,你可以根据需要在python对象中分割/追加/收集数据。

最简单的方法是在手动选择表格并将其复制到剪贴板后使用pandas函数pd.read_clipboard(),以便在excel或其他工具中打开csv文件。

# EYZ0:

此外,跟你的问题无关,但因为没人提过这件事:我在从UCI加载一些数据集(如seeds_dataset.txt)时遇到了同样的问题。在我的例子中,发生错误是因为一些分隔符的空格比真正的制表符\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)

在我的例子中,这是因为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)

标记数据错误。C错误:第3行有2个字段,见12

这个错误给出了解决问题“Expected 2 fields in line 3, saw 12”的线索,saw 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 )

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

此外,如果需要使用均匀的数据长度,可以将NaN值填充为0。如。对于聚类(k-means)

new_data = data.fillna(0)

在我的例子中,分隔符不是默认的“,”,而是Tab。

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

注意:“\t”并不像某些来源所建议的那样有效。“\\t”是必需的。

我相信解决方案,

,engine='python'
, error_bad_lines = False

将很好,如果它是虚拟列,你想删除它。 在我的例子中,第二行确实有更多的列,我希望这些列被积分,并且有列数= MAX(列)。< / p >

请参考下面我无法阅读的解决方案:

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)

你可以试试;

data = pd.read_csv('file1.csv', sep='\t')

有时在单元格中有逗号","。因此,熊猫不能读它。 尝试使用" "

分隔符
df = pd.read_csv(r'yourpath', delimiter=";")

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

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)

问题出在分隔符上。找出在数据中使用的分隔符类型,并如下所示指定它:

data = pd.read_csv('some_data.csv', sep='\t')

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

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

你可以使用:

pd.read_csv("mycsv.csv", delimiter=";")

熊猫1.4.4

它可以是文件的分隔符,将其作为文本文件打开,查找分隔符。然后,您将拥有可以为空且未命名的列,因为行包含太多分隔符。

因此,您可以使用pandas来处理它们并检查值。对我来说,这比在我的情况下跳过台词要好。

在我的例子中,问题是熊猫的版本,所以熊猫1.3.5非常有效。

检查是否使用正确的分隔符加载csv。

df = pd.read_csv(csvname, header=0, sep=",")