使用Python3,Pandas 0.12
我正在尝试将多个csv文件(总大小为7.9 GB)写入HDF5存储区,以便稍后处理。csv文件每个包含大约一百万行,15列,数据类型大多是字符串,但也有一些浮动。然而,当我试图读取csv文件时,我会收到以下错误:
Traceback (most recent call last):
File "filter-1.py", line 38, in <module>
to_hdf()
File "filter-1.py", line 31, in to_hdf
for chunk in reader:
File "C:Python33libsite-packagespandasioparsers.py", line 578, in __iter__
yield self.read(self.chunksize)
File "C:Python33libsite-packagespandasioparsers.py", line 608, in read
ret = self._engine.read(nrows)
File "C:Python33libsite-packagespandasioparsers.py", line 1028, in read
data = self._reader.read(nrows)
File "parser.pyx", line 706, in pandas.parser.TextReader.read (pandasparser.c:6745)
File "parser.pyx", line 740, in pandas.parser.TextReader._read_low_memory (pandasparser.c:7146)
File "parser.pyx", line 781, in pandas.parser.TextReader._read_rows (pandasparser.c:7568)
File "parser.pyx", line 768, in pandas.parser.TextReader._tokenize_rows (pandasparser.c:7451)
File "parser.pyx", line 1661, in pandas.parser.raise_parser_error (pandasparser.c:18744)
pandas.parser.CParserError: Error tokenizing data. C error: EOF inside string starting at line 754991
Closing remaining open files: ta_store.h5... done
编辑:
我设法找到了一个产生这个问题的文件。我觉得这是在读一个EOF角色。然而,我不知道如何克服这个问题。考虑到组合文件的大尺寸,我认为检查每个字符串中的每个字符太麻烦了。(即便如此,我仍然不确定该怎么办。)据我检查,csv文件中没有可能引发错误的奇怪字符。我还尝试将error_bad_lines=False
传递给pd.read_csv()
,但错误仍然存在。
我的代码如下:
# -*- coding: utf-8 -*-
import pandas as pd
import os
from glob import glob
def list_files(path=os.getcwd()):
''' List all files in specified path '''
list_of_files = [f for f in glob('2013-06*.csv')]
return list_of_files
def to_hdf():
""" Function that reads multiple csv files to HDF5 Store """
# Defining path name
path = 'ta_store.h5'
# If path exists delete it such that a new instance can be created
if os.path.exists(path):
os.remove(path)
# Creating HDF5 Store
store = pd.HDFStore(path)
# Reading csv files from list_files function
for f in list_files():
# Creating reader in chunks -- reduces memory load
reader = pd.read_csv(f, chunksize=50000)
# Looping over chunks and storing them in store file, node name 'ta_data'
for chunk in reader:
chunk.to_hdf(store, 'ta_data', mode='w', table=True)
# Return store
return store.select('ta_data')
return 'Finished reading to HDF5 Store, continuing processing data.'
to_hdf()
编辑
如果我进入引发CParserError EOF的CSV文件。。。并手动删除导致问题的行之后的所有行,csv文件将正确读取。然而,我删除的都是空白行。奇怪的是,当我手动更正错误的csv文件时,它们会被单独加载到商店中。但是当我再次使用多个文件的列表时,"false"文件仍然会返回错误。
我也遇到了类似的问题。用'EOF inside string'
列出的行有一个字符串,其中包含一个单引号('
)。当我添加选项quoting=csv.QUOTE_NONE
时,它解决了我的问题。
例如:
import csv
df = pd.read_csv(csvfile, header = None, delimiter="t", quoting=csv.QUOTE_NONE, encoding='utf-8')
我也有同样的问题,在将这两个参数添加到我的代码中后,问题就消失了。
read_csv(…
quoting=3
,error_bad_lines=False
)
我意识到这是一个老问题,但我想分享更多关于这个错误的根本原因以及@Selah的解决方案为什么有效的细节。
来自csv.py
文档字符串:
* quoting - controls when quotes should be generated by the writer.
It can take on any of the following module constants:
csv.QUOTE_MINIMAL means only when required, for example, when a
field contains either the quotechar or the delimiter
csv.QUOTE_ALL means that quotes are always placed around fields.
csv.QUOTE_NONNUMERIC means that quotes are always placed around
fields which do not parse as integers or floating point
numbers.
csv.QUOTE_NONE means that quotes are never placed around fields.
csv.QUOTE_MINIMAL
为默认值,"
为默认quotechar
。如果csv文件中的某个地方有一个quotechar,它将被解析为字符串,直到再次出现quotechar。如果您的文件有奇数个quotechar,那么在到达EOF
(文件末尾)之前,最后一个quotechars将不会关闭。还要注意,quotechar之间的任何内容都将被解析为单个字符串。即使有许多换行符(预计将被解析为单独的行),它们都会进入表的单个字段。因此,你在错误中得到的行号可能会产生误导。举例说明:
In[4]: import pandas as pd
...: from io import StringIO
...: test_csv = '''a,b,c
...: "d,e,f
...: g,h,i
...: "m,n,o
...: p,q,r
...: s,t,u
...: '''
...:
In[5]: test = StringIO(test_csv)
In[6]: pd.read_csv(test)
Out[6]:
a b c
0 d,e,fng,h,inm n o
1 p q r
2 s t u
In[7]: test_csv_2 = '''a,b,c
...: "d,e,f
...: g,h,i
...: "m,n,o
...: "p,q,r
...: s,t,u
...: '''
...: test_2 = StringIO(test_csv_2)
...:
In[8]: pd.read_csv(test_2)
Traceback (most recent call last):
...
...
pandas.errors.ParserError: Error tokenizing data. C error: EOF inside string starting at line 2
第一个字符串有2个(偶数)引号。因此,每个quotechar都是关闭的,csv被解析时没有错误,尽管可能不是我们所期望的。另一个字符串有3个(奇数)引号。最后一个没有关闭,达到EOF,因此出现错误。但我们在错误信息中看到的第2行是误导性的。我们期望4,但由于第一个和第二个quotechar之间的所有内容都被解析为字符串,所以我们的"p,q,r
行实际上是第二行。
这样做的内部循环将允许您检测"坏"文件(并进一步调查)
from pandas.io import parser
def to_hdf():
.....
# Reading csv files from list_files function
for f in list_files():
# Creating reader in chunks -- reduces memory load
try:
reader = pd.read_csv(f, chunksize=50000)
# Looping over chunks and storing them in store file, node name 'ta_data'
for chunk in reader:
chunk.to_hdf(store, 'ta_data', table=True)
except (parser.CParserError) as detail:
print f, detail
解决方案是在read_csv函数中使用参数engine='ython'。Pandas CSV解析器可以使用两个不同的"引擎"来解析CSV文件——Python或C(这也是默认的)。
pandas.read_csv(filepath, sep=',', delimiter=None,
header='infer', names=None,
index_col=None, usecols=None, squeeze=False,
..., engine=None, ...)
在Pandas文档中,Python引擎被描述为"较慢,但功能更完整"。
engine : {‘c’, ‘python’}
我的错误:
ParserError:标记数据时出错。C错误:字符串中存在EOF从第4488'行开始
通过在我的代码中添加delimiter="t"
解决为:
import pandas as pd
df = pd.read_csv("filename.csv", delimiter="t")
使用
engine="python",
error_bad_lines=False,
在CCD_ 15上。
完整的通话内容如下:
df = pd.read_csv(csvfile,
delimiter="t",
engine="python",
error_bad_lines=False,
encoding='utf-8')
对我来说,其他解决方案不起作用,让我非常头疼。error_bad_lines=False仍然给出错误C error: EOF inside string starting at line
。使用不同的引号也没有得到想要的结果,因为我不想在文本中使用引号。
我意识到Pandas 0.20中有一个错误。升级到0.21版本完全解决了我的问题。有关此错误的更多信息,请参阅:https://github.com/pandas-dev/pandas/issues/16559
注意:这可能与URL中提到的Windows相关。
在查找了几个小时的解决方案后,我终于找到了一个解决方案。
在不降低多处理效率的情况下消除这种C error: EOF inside string starting at line exception
的最佳方法是对输入数据进行预处理(如果有这样的机会)。
替换输入文件中的所有"\n"项,例如"、"或任何其他唯一符号序列(例如"aghr21*&")。然后,您将能够将数据读取到数据帧中。
读取数据后,您可能需要将所有唯一的符号序列('aghr21*&')替换回'\n'。
在尝试从Github存储库提取数据时遇到了类似的问题。一个简单的错误是,试图从git blob(html呈现的部分)而不是原始csv中提取数据。
如果您从git repo中提取数据,请确保您的链接不包括<repo name>/blob
,除非您对repo中的html代码特别感兴趣。
不涉及数据丢失的最简单解决方案是:
df = pd.read_csv(nome_do_arquivo, sep=",")