繁体   English   中英

Python Pandas 错误标记数据

[英]Python Pandas Error tokenizing data

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

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

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

我的代码很简单:

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

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

文件来自晨星

你也可以试试;

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

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

这可能是一个问题

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

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

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

在上面的代码中, sep定义了你的分隔符, header=None告诉熊猫你的源数据没有用于标题/列标题的行。 因此文档说:“如果文件不包含标题行,那么你应该明确地传递 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)

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

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

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

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

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

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

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

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

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

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

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

我也有这个问题,但也许是出于不同的原因。 我的 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 阅读器来避免。 希望 Pandas 的开发者以后可以更轻松地处理这种情况。

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

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

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

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

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

希望有帮助。

你可以试试;

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

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

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

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

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

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

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 解析引擎(这是默认引擎)有关。 也许改成蟒蛇会改变任何事情

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;博士
更改解析引擎,尽量避免数据中出现任何非分隔引号/逗号/空格。

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

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

在参数中使用分隔符

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

它会读。

尽管此问题的情况并非如此,但压缩数据也可能出现此错误。 显式设置kwarg compression的值解决了我的问题。

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

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

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

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

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

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

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

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

我发现在处理类似解析错误时有用的另一种方法是使用 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=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)

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

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

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

无关

此外,与您的问题无关,但因为没有人提到这一点:我在从 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)

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

尝试从链接读取 csv 数据时

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

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

我有一个与此类似的案例和设置

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

工作过

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

标记数据时出错。 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)

我相信解决方案,

,engine='python'
, error_bad_lines = False

如果它是虚拟列并且您想删除它会很好。 在我的情况下,第二行确实有更多的列,我希望这些列被整合并具有列数 = MAX(columns)。

请参考下面我在任何地方都看不到的解决方案:

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)

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

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

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

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

这就是我所做的。

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

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

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

对我而言,问题是在我的 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 (ie 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 英寸的测井记录打印很差:

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

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

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

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

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

我的代码很简单:

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

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

文件来自Morningstar

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

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

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

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

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

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

只需添加 - header=None

希望这可以帮助!!

问题可能与文件问题有关,就我而言,问题是在重命名文件后解决的。 还没有找到原因。

我遇到了带有引号的错误。 我使用映射软件,在导出逗号分隔文件时,该软件会在文本项周围加上引号。 使用引号(例如'=英尺和“ =英寸)的文本可能会出现问题。请考虑以下示例,该示例指出5英寸的测井记录质量较差:

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

使用5"作为5 inch简写形式最终会在工作中投入一把扳手error_bad_lines=False会简单地去除多余的引号,但是Pandas会崩溃而没有上述error_bad_lines=False参数。

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

已经提到了大多数有用的答案,但是我建议将熊猫数据帧另存为实木复合地板文件。 实木复合地板文件没有此问题,并且它们同时具有存储效率。

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

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

您可以使用:

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

Pandas 1.4.4

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM