web-dev-qa-db-ja.com

Pandas ParserError EOF複数のcsvファイルをHDF5に読み込むときの文字

Python3を使用して、Pandas 0.12

複数のcsvファイル(合計サイズは7.9 GB)をHDF5ストアに書き込んで、後で処理しようとしています。 csvファイルにはそれぞれ約100万行が含まれ、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ファイルにエラーを引き起こす可能性のある奇妙な文字はありません。また、pd.read_csv()error_bad_lines=Falseを渡してみました。 、しかしエラーは続く。

私のコードは次のとおりです:

# -*- 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」ファイルでもエラーが返されます。

26
Matthijs

同様の問題がありました。 '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')
69
Selah

私は同じ問題を抱えており、これら2つのパラメーターをコードに追加した後、問題はなくなりました。

read_csv(...quoting=3error_bad_lines=False

13
weefwefwqg3

このような内部ループを作成すると、「不良」ファイルを検出できます(さらに調査できます)。

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
5
Jeff

これは古い質問だと思いますが、このエラーの根本的な原因と、@ Selahの解決策が機能する理由について、もう少し詳しく説明したいと思います。

csv.py docstringから:

    * 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(ファイルの終わり)に到達する前に閉じられません。また、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,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はエラーなしで解析されます。もう1つの文字列には、3(奇数)の引用符があります。最後の1つは閉じられておらず、EOFに達しているため、エラーが発生しています。ただし、エラーメッセージで表示される2行目は誤解を招く可能性があります。4が必要ですが、最初と2番目のquotecharの間のすべてが"p,q,r行は実際には2番目の文字列として解析されます。

4
MJB

解決策は、read_csv関数でパラメーターengine = ’python’を使用することです。 Pandas CSVパーサーは、2つの異なる「エンジン」を使用してCSVファイルを解析できます– PythonまたはC(これもデフォルトです)。

pandas.read_csv(filepath, sep=',', delimiter=None, 
            header='infer', names=None, 
            index_col=None, usecols=None, squeeze=False, 
            ..., engine=None, ...)

Pythonエンジンは Pandasのドキュメント で「遅いが、より機能が充実している」と説明されています。

engine : {‘c’, ‘python’}
3
Aman Singh

私にとって、他の解決策は機能せず、私はかなり頭痛の種になりました。 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関連である可能性があります。

0
Guido