pandas.parser.CParserError:标记数据时出错
- 2024-12-03 08:45:00
- admin 原创
- 167
问题描述:
我正在尝试使用 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
模块还是其他语言?
解决方案 1:
你也可以尝试;
data = pd.read_csv('file1.csv', on_bad_lines='skip')
请注意,这将导致跳过有问题的行。如果您不希望出现太多错误行,并且希望(至少)知道它们的数量和 ID,请使用on_bad_lines='warn'
。对于错误行的高级处理,您可以传递一个可调用函数。
编辑
对于 Pandas <1.3.0 版本,请尝试
data = pd.read_csv("file1.csv", error_bad_lines=False)
按照pandas API 参考。
解决方案 2:
这可能是一个问题
数据中的分隔符
第一行,正如@TomAugspurger 指出的那样
要解决此问题,请尝试在调用时指定sep
and/or参数。例如,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() + '
' + 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)
解决方案 3:
这肯定是分隔符的问题,因为大多数 csv CSV 都是使用创建的sep='/t'
,因此尝试使用分隔符使用read_csv
制表符。因此,尝试使用以下代码行打开。( )
`/t`
data=pd.read_csv("File_path", sep=' ')
解决方案 4:
解析器对文件头感到困惑。它读取第一行并从该行推断出列数。但前两行并不代表文件中的实际数据。
尝试一下data = pd.read_csv(path, skiprows=2)
解决方案 5:
我遇到了这个问题,我试图读取 CSV 而不传递列名。
df = pd.read_csv(filename, header=None)
我事先在列表中指定了列名,然后将它们传递到 中names
,它立即解决了这个问题。如果您没有设置列名,您可以创建与数据中可能存在的最大列数一样多的占位符名称。
col_names = ["col1", "col2", "col3", ...]
df = pd.read_csv(filename, names=col_names)
解决方案 6:
您的 CSV 文件的列数可能不定,并且会read_csv
根据前几行推断出列数。在这种情况下,有两种方法可以解决此问题:
1)将 CSV 文件更改为具有最大列数的虚拟第一行(并指定header=[0]
)
2)或者使用names = list(range(0,N))
N 为最大列数。
解决方案 7:
我也遇到过这个问题,但可能是出于不同的原因。我的 CSV 中有一些尾随逗号,它们添加了 pandas 试图读取的附加列。使用下面的方法有效,但它只是忽略了错误的行:
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 开发人员将来能够更轻松地处理这种情况。
解决方案 8:
以下对我有用(我发布了这个答案,因为我在 Google Colaboratory Notebook 中遇到了这个问题):
df = pd.read_csv("/path/foo.csv", delimiter=';', skiprows=0, low_memory=False)
解决方案 9:
你可以尝试;
data = pd.read_csv('file1.csv', sep=' ')
解决方案 10:
我遇到了同样的问题。pd.read_table()
在同一个源文件上使用似乎有效。我无法找出原因,但对于我的情况来说,这是一个有用的解决方法。也许更有知识的人可以更清楚地解释为什么它有效。
编辑:我发现,当文件中的某些文本与实际数据的格式不同时,就会出现此错误。这通常是页眉或页脚信息(大于一行,因此 skip_header 不起作用),它们之间的逗号数量与实际数据不同(使用 read_csv 时)。使用 read_table 时,使用制表符作为分隔符,这可以避免用户当前的错误,但会引入其他错误。
我通常通过将额外的数据读入文件然后使用 read_csv() 方法来解决这个问题。
具体解决方案可能因您的实际文件而异,但这种方法在很多情况下对我都有效
解决方案 11:
我自己也遇到过几次这个问题。几乎每次都是因为我试图打开的文件一开始就不是正确保存的 CSV。所谓“正确”,是指每行都有相同数量的分隔符或列。
通常,这是因为我在 Excel 中打开了 CSV,然后错误地保存了它。尽管文件扩展名仍然是 .csv,但纯 CSV 格式已被改变。
使用 pandas to_csv 保存的任何文件都将正确格式化,并且不会出现此问题。但如果您使用其他程序打开它,它可能会改变结构。
解决方案 12:
标记数据时出错。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)
解决方案 13:
我使用的数据集中有很多与格式无关的引号(“)。我可以通过为 包含此参数来修复该错误read_csv()
:
quoting=3 # 3 correlates to csv.QUOTE_NONE for pandas
解决方案 14:
我在尝试读取带有空格、逗号和引号的制表符分隔表时遇到了类似的问题:
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=' ', 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=' ', 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(' ',''))
counts = pd.read_table(input, sep=' ', index_col=2, header=None, engine='python')
tl;dr
更改解析引擎,尽量避免数据中出现任何非分隔引号/逗号/空格。
解决方案 15:
在参数中使用分隔符
pd.read_csv(filename, delimiter=",", encoding='utf-8')
它会读。
解决方案 16:
据我所知,在查看了您的文件后,问题在于您尝试加载的 csv 文件有多个表。有空行,或包含表标题的行。尝试查看此Stackoverflow 答案。它展示了如何以编程方式实现这一点。
另一种动态方法是使用csv 模块,一次读取每一行并进行健全性检查/正则表达式,以推断该行是否为 (title/header/values/blank)。这种方法还有一个优点,就是您可以根据需要在 python 对象中拆分/附加/收集数据。
最简单的方法是pd.read_clipboard()
手动选择并将表格复制到剪贴板后使用 pandas 函数,以防您可以在 excel 或其他地方打开 csv。
不相关:
此外,与您的问题无关,但因为没有人提到这一点:我在加载某些数据集(例如seeds_dataset.txt
来自 UCI 的数据集)时遇到了同样的问题。 在我的情况下,发生错误是因为某些分隔符的空格比真正的制表符多
。 例如,请参阅下面的第 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
因此, +
在分隔符模式中使用 而不是
。
data = pd.read_csv(path, sep=' +`, header=None)
解决方案 17:
对于那些在 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')
解决方案 18:
我相信解决方案,
,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)
解决方案 19:
虽然这个问题不是这种情况,但压缩数据也可能出现此错误。明确设置值kwarg
compression
解决了我的问题。
result = pandas.read_csv(data_source, compression='gzip')
解决方案 20:
在我的情况下,分隔符不是默认的“,”而是Tab。
pd.read_csv(file_name.csv, sep='\\t',lineterminator='\\r', engine='python', header='infer')
注意:"\t" 并未像某些来源所建议的那样起作用。"\\t" 是必需的。
解决方案 21:
我遇到了这个问题的多种解决方案。很多人也给出了最好的答案。但对于初学者,我认为以下两种方法就足够了:
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=' ')
解决方案 22:
简单解决方法:在 excel 中打开 csv 文件并将其保存为 csv 格式的不同名称文件。再次尝试将其导入 spyder,您的问题将得到解决!
解决方案 23:
问题出在分隔符上。找出数据中使用的分隔符类型,并按如下所示指定它:
data = pd.read_csv('some_data.csv', sep=' ')
解决方案 24:
有时问题不在于如何使用 Python,而在于原始数据。
我收到了这个错误消息
Error tokenizing data. C error: Expected 18 fields in line 72, saw 19.
原来,列描述中有时会出现逗号。这意味着需要清理 CSV 文件或使用其他分隔符。
解决方案 25:
我发现在处理类似解析错误时有用的另一种方法是使用 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 模块对于格式不佳的逗号分隔文件更加强大,因此通过这种方式可以成功解决这些问题。
解决方案 26:
以下命令序列有效(我丢失了数据的第一行 - 没有标题 = 没有存在 -,但至少它加载了):
`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)
解决方案 27:
这就是我所做的。
sep='::'
解决了我的问题:
data=pd.read_csv('C:\\Users\\HP\\Downloads\\NPL ASSINGMENT 2 imdb_labelled\\imdb_labelled.txt',engine='python',header=None,sep='::')
解决方案 28:
有时单元格中会有逗号“,”。因此,pandas 无法读取它。请尝试使用“;”作为分隔符
df = pd.read_csv(r'yourpath', delimiter=";")
解决方案 29:
您可以使用:
pd.read_csv("mycsv.csv", delimiter=";")
Pandas 1.4.4
它可以是文件的分隔符,将其作为文本文件打开,查找分隔符。然后,您将看到列可能为空且未命名,因为行包含太多分隔符。
因此,您可以使用 pandas 处理它们并检查值。对我来说,这比跳过行要好。
解决方案 30:
检查您是否使用正确的分隔符加载 csv。
df = pd.read_csv(csvname, header=0, sep=",")