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

Mat*_*ijs 23 python csv hdf5 python-3.x pandas

使用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 
Run Code Online (Sandbox Code Playgroud)

编辑:

我设法找到一个产生这个问题的文件.我认为它正在阅读一个EOF角色.但是我无法克服这个问题.鉴于组合文件的大小,我认为检查每个字符串中的每个单个字符太麻烦了.(即便如此,我仍然不确定该怎么做.)据我检查,csv文件中没有可能引发错误的奇怪字符.我也试过路过error_bad_lines=Falsepd.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()
Run Code Online (Sandbox Code Playgroud)

编辑

如果我进入引发CParserError EOF的CSV文件...并手动删除导致问题的行之后的所有行,则正确读取csv文件.但是我删除的所有内容都是空行.奇怪的是,当我手动纠正错误的csv文件时,它们会被单独加载到商店中.但是当我再次使用多个文件的列表时,'false'文件仍然会返回错误.

Sel*_*lah 74

我遇到了类似的问题.使用'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')
Run Code Online (Sandbox Code Playgroud)

  • 这对我有用,但如果有人能解释为什么这有效,那就太好了 (3认同)
  • 这是一个最佳解决方案 (2认同)

wee*_*qg3 14

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

read_csv(... quoting=3,error_bad_lines=False)


MJB*_*MJB 10

我意识到这是一个老问题,但我想分享更多有关此错误根本原因的详细信息以及@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.
Run Code Online (Sandbox Code Playgroud)

csv.QUOTE_MINIMAL是默认值并且"是默认值quotechar。如果您的 csv 文件中的某个地方有一个 quotechar,它将被解析为一个字符串,直到再次出现该 quotechar。如果您的文件有奇数个quotechars,那么在到达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
Run Code Online (Sandbox Code Playgroud)

第一个字符串有 2 个(偶数)quotechars。所以每个quotechar都被关闭并且csv被解析没有错误,尽管可能不是我们所期望的。另一个字符串有 3 个(奇数)quotechars。最后一个没有关闭并且到达 EOF 因此错误。但是我们在错误消息中得到的第 2 行具有误导性。我们期望 4,但由于第一个和第二个 quotechar 之间的所有内容都被解析为字符串,我们的"p,q,r行实际上是第二个。


Ama*_*ngh 8

解决办法是在read_csv函数中使用参数engine=\xe2\x80\x99python\xe2\x80\x99。Pandas CSV 解析器可以使用两个不同的 \xe2\x80\x9cengines\xe2\x80\x9d 来解析 CSV 文件 \xe2\x80\x93 Python 或 C(这也是默认的)。

\n\n
pandas.read_csv(filepath, sep=\',\', delimiter=None, \n            header=\'infer\', names=None, \n            index_col=None, usecols=None, squeeze=False, \n            ..., engine=None, ...)\n
Run Code Online (Sandbox Code Playgroud)\n\n

Pandas 文档中将Python 引擎描述为 \xe2\x80\x9c较慢,但功能更完整\xe2\x80\x9d 。

\n\n
engine : {\xe2\x80\x98c\xe2\x80\x99, \xe2\x80\x98python\xe2\x80\x99}\n
Run Code Online (Sandbox Code Playgroud)\n

  • 这是最好的答案。也在 https://www.shanelynn.ie/pandas-csv-error-error-tokenizing-data-c-error-eof-inside-string-starting-at-line/ 中进行了解释 (3认同)

Jef*_*eff 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
Run Code Online (Sandbox Code Playgroud)

  • 另外,我认为第一行代码是`来自pandas import parser`而不是`来自pandas.io import parser`?因为后者无法与我的熊猫0.15.0一起使用 (2认同)