我有一个包含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的违规行不是一种选择,这些行包含有价值的信息。
有人知道解决这个问题吗?
答案 0 :(得分:0)
由于我没有找到完全解决问题的答案,所以这是我的工作:我发现明确地使用选项names=('col1', 'col2', 'stringColumn' ... 'column25', '', '', '')
传递列名允许我读取文件。它迫使我阅读和解析每一列,这是不理想的,因为我只需要大约一半,但至少我现在可以阅读该文件。
我将参数组合names
和usecols
并且不起作用,如果有人有其他解决方案,我会很高兴听到它。
答案 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