Pandas CParserError:错误标记数据

时间:2016-04-28 12:48:27

标签: python csv pandas

我有一个包含25列的大型csv文件,我想将其视为pandas数据帧。我正在使用pandas.read_csv()。 问题是某些行有额外的列,如下所示:

        col1   col2   stringColumn   ...   col25
1        12      1       str1                 3
...
33657    2       3       str4                 6       4    3 #<- that line has a problem
33658    1      32       blbla                 #<-some columns have missing data too 

当我尝试阅读时,我收到错误

CParserError: Error tokenizing data. C error: Expected 25 fields in line 33657, saw 28

如果额外值出现在第一行中,则不会发生此问题。例如,如果我将值添加到同一文件的第三行,它可以正常工作

#that example works: 
           col1   col2   stringColumn   ...   col25
    1        12      1       str1                 3
    2        12      1       str1                 3
    3        12      1       str1                 3       f    4
    ...
    33657    2       3       str4                 6       4    3 #<- that line has a problem
    33658    1      32       blbla                 #<-some columns have missing data too 

我的猜测是pandas检查第一行(n)以确定列数,如果之后有额外的列,则解析它时会出现问题。

跳过违反建议here的违规行不是一种选择,这些行包含有价值的信息。

有人知道解决这个问题吗?

3 个答案:

答案 0 :(得分:0)

由于我没有找到完全解决问题的答案,所以这是我的工作:我发现明确地使用选项names=('col1', 'col2', 'stringColumn' ... 'column25', '', '', '')传递列名允许我读取文件。它迫使我阅读和解析每一列,这是不理想的,因为我只需要大约一半,但至少我现在可以阅读该文件。 我将参数组合namesusecols并且不起作用,如果有人有其他解决方案,我会很高兴听到它。

答案 1 :(得分:0)

在我的帖子中,我提到不使用&#34; error_bad_lines&#34; = pandas.read_csv中的False。我认为实际上这样做是更合适和更优雅的解决方案。我发现这篇文章非常有用。

Can I redirect the stdout in python into some sort of string buffer?

我在答案中显示的代码中加了一点点。

import sys
import re
from cStringIO import StringIO
import pandas as pd

fake_csv = '''1,2,3\na,b,c\na,b,c\na,b,c,d,e\na,b,c\na,b,c,d,e\na,b,c\n''' #bad data
fname = "fake.csv"
old_stderr = sys.stderr
sys.stderr = mystderr = StringIO()

df1 = pd.read_csv(StringIO(fake_csv),
                  error_bad_lines=False)

sys.stderr = old_stderr 
log = mystderr.getvalue()
isnum = re.compile("\d+")

lines_skipped_log = [
    isnum.findall(i) + [fname]\
    for i in log.split("\n") if isnum.search(i)
        ]

columns=["line_num","flds_expct","num_fields","file"]
lines_skipped_log.insert(0,columns)

从那里,您可以使用lines_skipped_log执行任何操作,例如输出到csv,创建数据帧等。

也许你有一个充满文件的目录。您可以从每个日志中创建一个pandas数据框列表并进行连接。从那里,您将获得一个记录,其中包含跳过的行以及触手可及的文件(字面意思!)。

答案 2 :(得分:0)

可能的解决方法是指定列名称。请参阅我的回答类似的问题:https://stackoverflow.com/a/43145539/6466550