2013-08-02 5 views
13

Mit Python3, Pandas 0,12Pandas ParserError EOF-Zeichen, wenn mehrere CSV-Dateien zu HDF5

Lesen Ich versuche, mehrere CSV-Dateien zu schreiben (Gesamtgröße beträgt 7,9 GB) an einem HDF5 Speicher später weiter zu verarbeiten. Die CSV-Dateien enthalten jeweils etwa eine Million Zeilen, 15 Spalten und Datentypen sind meist Strings, aber einige Floats. Allerdings, wenn ich versuche, die CSV-Dateien, die ich erhalte die folgende Störung zu lesen:

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 

bearbeiten:

ich es geschafft, eine Datei zu finden, die dieses Problem erzeugt. Ich denke, es liest einen EOF-Charakter. Ich habe jedoch keine Ahnung, um dieses Problem zu lösen. Angesichts der großen Größe der kombinierten Dateien ist es meiner Meinung nach zu mühsam, jedes einzelne Zeichen in jeder Zeichenfolge zu überprüfen. (Selbst dann würde ich immer noch nicht sicher sein, was zu tun ist.) Soweit ich überprüft habe, gibt es keine seltsamen Zeichen in den CSV-Dateien, die den Fehler auslösen könnten. Ich habe auch versucht, error_bad_lines=False zu pd.read_csv() zu übergeben, aber der Fehler bleibt bestehen.

Mein Code ist folgende:

# -*- 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() 

bearbeiten

Wenn ich in die CSV-Datei gehen, die die CParserError EOF wirft ... und manuell löschen alle Zeilen nach der Zeile, die verursacht wird, Das Problem, die CSV-Datei wird richtig gelesen. Aber alles, was ich lösche, sind sowieso leere Zeilen. Das Seltsame ist, dass wenn ich die fehlerhaften CSV-Dateien manuell korrigieren, sie einzeln in den Laden geladen werden. Aber wenn ich wieder eine Liste von mehreren Dateien verwende, geben die 'falschen' Dateien immer noch Fehler zurück.

+0

übergeben Sie nicht die '' mode = 'w'''; Sie kürzen die hdf-Datei bei jeder Iteration – Jeff

+0

Sie können versuchen, den CParserError zu fangen und nur diese Datei überspringen (bis Sie es beheben) – Jeff

+0

Hallo Jeff, wie empfehlen Sie, dass ich den CParserError fangen. Es ist viel zu mühsam, jede einzelne Datei zu überprüfen. – Matthijs

Antwort

5

Machen Sie Ihre innere Schleife wie diese Sie die ‚schlechten‘ Datei (und weiter zu untersuchen) erfassen können

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 
+0

Hallo Jeff, danke! Es funktioniert und ich habe herausgefunden, welche Dateien/Zeilen das Problem verursachen. Jetzt kann ich versuchen, diese Dateien manuell zu korrigieren, aber ich hätte lieber eine programmatische Lösung. Also muss ich verstehen, was eigentlich der Fehler ist, den ich zurückgebe und welchen Code ich schreibe, der sich automatisch um dieses Problem kümmert. – Matthijs

+0

können Sie versuchen, einen '' lineterminator'' (was im Grunde genommen '' n'' auf linux (oder '' \ n \ r'' auf Windows Ich denke) zu sagen. Und im schlimmsten Fall bekommen Sie eine schlechte Zeile Ungültiger Terminator wird in die nächste Zeile gesetzt) ​​..... muss aber zuerst sehen, was falsch ist: http://pandas.pydata.org/pandas-docs/dev/io.html#csv-text-files – Jeff

+0

Das Seltsame ist, dass, wenn ich die fehlerhaften CSV-Dateien manuell korrigieren, sie einzeln in den Laden geladen werden.Wenn ich wieder 'glob' verwenden, um eine Reihe von Dateien zu lesen, geben diese Dateien immer noch Fehler zurück – Matthijs

38

Ich hatte ein ähnliches Problem. Die mit dem 'EOF-Inside-String' aufgelistete Zeile enthielt eine Zeichenfolge, die ein einfaches Anführungszeichen enthielt. Als ich die Option quoting = csv.QUOTE_NONE hinzugefügt habe, habe ich mein Problem behoben.

Zum Beispiel:

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

ist dies eine optimale Lösung – DACW

+2

Ich habe auch 'import csv' hinzugefügt – user1700890

4

Ich habe das gleiche Problem, und nachdem diese beiden params zu meinem Code hinzufügen, ist das Problem verschwunden.

+0

Das funktioniert wie Charme. In einer Zeile ist ein Fehler aufgetreten. Nach der Ausführung mit der obigen Option habe ich die folgende Meldung erhalten: 'Zeile 192 übersprungen: erwartet 5 Felder, sah 74' –

0

Für mich funktionierten die anderen Lösungen nicht und verursachten mir ziemlich Kopfschmerzen. error_bad_lines = False gibt immer noch den Fehler C error: EOF inside string starting at line. Die Verwendung einer anderen Quotierung brachte auch nicht die gewünschten Ergebnisse, da ich keine Zitate in meinem Text haben wollte.

Ich erkannte, dass es in Pandas 0,20 einen Bug gab. Das Upgrade auf Version 0.21 hat mein Problem vollständig gelöst. Weitere Informationen zu diesem Fehler finden Sie unter: https://github.com/pandas-dev/pandas/issues/16559

Hinweis: Dies kann Windows-bezogen sein, wie in der URL erwähnt.

+0

Das funktioniert nicht - auch nach dem Upgrade auf Pandas-0.22.0 bekomme ich den gleichen Fehler –

1

Die Lösung besteht darin, den Parameter engine = 'python' in der Funktion read_csv zu verwenden. Der Pandas CSV-Parser kann zwei verschiedene "Engines" verwenden, um eine CSV-Datei zu analysieren - Python oder C (was auch der Standard ist).

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

Der Python Maschine beschrieben „langsamer, aber mehr feature complete ist“ zu sein in den Pandas documentation.

engine : {‘c’, ‘python’}