38

使用 Python3,熊猫 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=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()

编辑

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

4

9 回答 9

132

我有一个类似的问题。列有“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')
于 2015-04-24T20:43:41.503 回答
27

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

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

于 2017-02-19T21:01:19.680 回答
12

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

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

于 2018-11-06T13:57:10.397 回答
6

像这样制作您的内部循环将允许您检测“坏”文件(并进一步调查)

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
于 2013-08-02T13:10:06.737 回答
4

解决方法是在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 文档中,Python 引擎被描述为“<em>更慢,但功能更完整” 。

engine : {‘c’, ‘python’}
于 2017-12-05T06:36:18.523 回答
1

我的错误:

ParserError:错误标记数据。C 错误:字符串中的 EOF 从第 4488 行开始

通过添加delimiter="\t"我的代码解决了:

import pandas as pd
df = pd.read_csv("filename.csv", delimiter="\t")
于 2022-02-17T04:59:33.023 回答
0

对我来说,其他解决方案都不起作用,让我很头疼。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 相关。

于 2017-11-07T14:03:57.200 回答
0

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

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

于 2021-02-26T04:11:41.530 回答
0

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

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

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

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

于 2020-05-19T19:34:05.010 回答