将多个csv文件读取到HDF5时,Pandas ParserError EOF字符

时间:2013-08-02 11:40:37

标签: python csv python-3.x pandas hdf5

使用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:\Python33\lib\site-packages\pandas\io\parsers.py", line 578, in __iter__
    yield self.read(self.chunksize)
  File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 608, in read
    ret = self._engine.read(nrows)
  File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 1028, in read
    data = self._reader.read(nrows)
  File "parser.pyx", line 706, in pandas.parser.TextReader.read (pandas\parser.c:6745)
  File "parser.pyx", line 740, in pandas.parser.TextReader._read_low_memory (pandas\parser.c:7146)
  File "parser.pyx", line 781, in pandas.parser.TextReader._read_rows (pandas\parser.c:7568)
  File "parser.pyx", line 768, in pandas.parser.TextReader._tokenize_rows (pandas\parser.c:7451)
  File "parser.pyx", line 1661, in pandas.parser.raise_parser_error (pandas\parser.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'文件仍然会返回错误。

8 个答案:

答案 0 :(得分:67)

我有类似的问题。在字符串&#39;内列出了&#39; EOF的行有一个字符串,其中包含单引号。当我添加选项quoting = csv.QUOTE_NONE时,它解决了我的问题。

例如:

import csv
df = pd.read_csv(csvfile, header = None, delimiter="\t", quoting=csv.QUOTE_NONE, encoding='utf-8')

答案 1 :(得分:11)

我遇到了同样的问题,在将这两个参数添加到我的代码后,问题就消失了。

  

read_csv(... quoting=3error_bad_lines=False

答案 2 :(得分:5)

使这样的内循环可以让你检测'坏'文件(并进一步调查)

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

答案 3 :(得分:3)

解决方案是在read_csv函数中使用参数engine ='python'。 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 documentation中的Python引擎被描述为“更慢,但功能更完整”。

engine : {‘c’, ‘python’}

答案 4 :(得分:3)

我意识到这是一个古老的问题,但是我想分享更多有关此错误的根本原因以及@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。如果您的文件中的引号字符数为奇数,则最后一个在到达EOF(文件末尾)之前不会关闭。另外请注意,quotechars之间的任何内容都将解析为单个字符串。即使有很多换行符(预计将被解析为单独的行),它们也都进入表的单个字段中。因此,您在错误中得到的行号可能会引起误解。为了举例说明,请考虑以下内容:

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,f\ng,h,i\nm  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个(偶数)quotechars。因此,每个quotechar均已关闭,并且csv被解析而没有错误,尽管可能不是我们期望的那样。另一个字符串有3个(奇数)quotechars。最后一个未关闭,并且到达EOF,因此出错。但是我们在错误消息中得到的第2行具有误导性。我们期望4,但是由于第一和第二quotechar之间的所有内容都被解析为字符串,因此我们的"p,q,r行实际上是第二行。

答案 5 :(得分:0)

对我来说,其他解决方案不起作用,让我非常头疼。 error_bad_lines = False仍然会给出错误import requests from bs4 import BeautifulSoup import csv response = requests.get('https://stackoverflow.com/users?page=3&tab=reputation&filter=week').text soup = BeautifulSoup(response, 'lxml') for items in soup.select('.user-details'): name = items.select("a")[0].text location = items.select(".user-location")[0].text reputation = items.select(".reputation-score")[0].text print(name,location,reputation) with open('stackdata.csv','a',newline='') as csv_file: writer = csv.writer(csv_file) writer.writerow([name,location,reputation]) 。使用不同的引文也没有给出所需的结果,因为我不希望在我的文本中引用。

我意识到Pandas 0.20中有一个错误。升级到0.21版完全解决了我的问题。有关此错误的更多信息,请参阅:https://github.com/pandas-dev/pandas/issues/16559

注意:这可能与URL中提到的Windows相关。

答案 6 :(得分:0)

寻找了几个小时的解决方案之后,我终于想出了一种解决方法。

在不降低效率的情况下消除此C error: EOF inside string starting at line exception的最佳方法是对输入数据进行预处理(如果有机会的话)。

将输入文件中的所有'\ n'条目替换为例如','或任何其他唯一符号序列(例如'aghr21 *&')。然后,您将能够将数据读取_csv到数据框中。

读取数据后,您可能希望替换所有唯一的符号序列('aghr21 *&'),重新回到'\ n'。

答案 7 :(得分:0)

尝试从 Github 存储库中提取数据时遇到了类似的问题。一个简单的错误,试图从 git blob(html 渲染部分)而不是原始 csv 中提取数据。

如果您从 git 存储库中提取数据,请确保您的链接不包含“<存储库名称>/blob”,除非您对存储库中的 html 代码特别感兴趣