在 Pandas read_csv 期间标记数据时出错。如何真正看到坏线?
Posted
技术标签:
【中文标题】在 Pandas read_csv 期间标记数据时出错。如何真正看到坏线?【英文标题】:Error tokenizing data during Pandas read_csv. How to actually see the bad lines? 【发布时间】:2016-12-18 13:23:48 【问题描述】:我有一个大的 csv,我按如下方式加载
df=pd.read_csv('my_data.tsv',sep='\t',header=0, skiprows=[1,2,3])
我在加载过程中遇到了几个错误。
首先,如果我不指定warn_bad_lines=True,error_bad_lines=False
,我会得到:
标记数据时出错。 C 错误:预计第 329867 行中有 22 个字段,见 24
其次,如果我使用上面的选项,我现在得到:
CParserError:标记数据时出错。 C 错误:字符串中的 EOF 从第 32357585 行开始
问题是:我如何查看这些坏线以了解发生了什么?是否有可能让read_csv
返回这些虚假行?
我尝试了以下提示 (Pandas ParserError EOF character when reading multiple csv files to HDF5):
from pandas import parser
try:
df=pd.read_csv('mydata.tsv',sep='\t',header=0, skiprows=[1,2,3])
except (parser.CParserError) as detail:
print detail
但还是得到了
标记数据时出错。 C 错误:预计第 329867 行中有 22 个字段,见 24
【问题讨论】:
你检查了第一个答案吗?会是特殊字符吗? ***.com/questions/18016037/… 第 32357585 行的数据是什么?这可能会提供一些线索并检查熊猫版本,github.com/pydata/pandas/issues/11654 是的,这就是问题所在。如何读取这条数据线? 如果是 CSV,在 CSV 中打开它(假设是 windows 框)(或)使用其他一些文件读取 API 来首先打印和理解数据,一旦你知道那里有什么,那么你可以尝试使用 pandas 找到解决方法。 Pandas 读取前几行,确定 dtypes,然后读取确定的 dtypes 中的其余数据。有时这会导致对字符串的误解。low_memory
只会导致 pandas 在读取所有数据后创建数据类型。它会导致内存中的数据重复。但你是对的,它可能对你的情况没有帮助。其他建议怎么样?
【参考方案1】:
我将分两部分给出答案:
第 1 部分: 操作员询问如何输出这些坏行,要回答这个问题,我们可以在这样的简单代码中使用 python csv 模块:
import csv
file = 'your_filename.csv' # use your filename
lines_set = set([100, 200]) # use your bad lines numbers here
with open(file) as f_obj:
for line_number, row in enumerate(csv.reader(f_obj)):
if line_number > max(lines_set):
break
elif line_number in lines_set: # put your bad lines numbers here
print(line_number, row)
我们也可以把它放在更通用的函数中:
import csv
def read_my_lines(file, lines_list, reader=csv.reader):
lines_set = set(lines_list)
with open(file) as f_obj:
for line_number, row in enumerate(csv.reader(f_obj)):
if line_number > max(lines_set):
break
elif line_number in lines_set:
print(line_number, row)
if __name__ == '__main__':
read_my_lines(file='your_filename.csv', lines_list=[100, 200])
part2:你得到错误的原因:
如果没有您使用的文件样本,就很难诊断出这样的问题。 但你应该试试这个..
pd.read_csv(filename)
它解析文件没有错误吗?如果是这样,我会解释原因。
列数是从第一行推断出来的。
通过使用 skiprows 和 header=0
,您转义了前 3 行,我猜它包含列名或应该包含正确列数的标题。
基本上你限制了解析器正在做什么。
所以解析时不要跳过,或者 header=0
然后重新索引到您以后需要的内容。
注意:
如果您不确定文件中使用的分隔符使用sep=None
,但它会更慢。
来自 pandas.read_csv 文档:
sep : str,默认使用“,”分隔符。如果 sep 为 None,则 C 引擎 不能自动检测分隔符,但是python解析 引擎可以,这意味着后者将被使用并自动检测 Python 的内置嗅探器工具 csv.Sniffer 的分隔符。在 此外,超过 1 个字符且不同于 '\s+' 的分隔符 将被解释为正则表达式,也会强制使用 Python 解析引擎。请注意,正则表达式分隔符很容易出现 忽略引用的数据。正则表达式示例:'\r\t'
link
【讨论】:
【参考方案2】:就我而言,添加分隔符有帮助:
data = pd.read_csv('/Users/myfile.csv', encoding='cp1251', sep=';')
【讨论】:
【参考方案3】:我们可以从错误中获取行号并打印行以查看它的样子
试试:
import subprocess
import re
from pandas import parser
try:
filename='mydata.tsv'
df=pd.read_csv(filename,sep='\t',header=0, skiprows=[1,2,3])
except (parser.CParserError) as detail:
print detail
err=re.findall(r'\b\d+\b', detail) #will give all the numbers ['22', '329867', '24'] line number is at index 1
line=subprocess.check_output("sed -n %s %s" %(str(err[1])+'p',filename),stderr=subprocess.STDOUT,shell=True) # shell command 'sed -n 2p filename' for printing line 2 of filename
print 'Bad line'
print line # to see line
【讨论】:
以上是关于在 Pandas read_csv 期间标记数据时出错。如何真正看到坏线?的主要内容,如果未能解决你的问题,请参考以下文章
pandas使用read_csv函数读取文件时指定数据列的数据类型pandas使用read_csv函数读取文件时通过keep_default_na参数设置缺失值替换为空字符串
如何在使用 pandas.read_csv 读取 csv 文件时将 pandas.dataframe 中的元素转换为 np.float?
如何在使用 pandas.read_csv 读取 csv 文件时将 pandas.dataframe 中的元素转换为 np.float?