Panda ParserError carattere EOF durante la lettura più file csv per HDF5

Utilizzando Python3, Panda 0.12

Sto cercando di scrivere più file csv (dimensione totale è di 7.9 GB) per un HDF5 negozio per elaborare in seguito in poi. Il file csv contiene circa un milione di righe, ognuna delle quali, a 15 colonne e i tipi di dati sono per lo più le corde, ma alcuni carri. Tuttavia, quando sto cercando di leggere il file csv ottengo il seguente errore:

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 

Modifica:

Sono riuscito a trovare un file che ha prodotto questo problema. Penso che la lettura di un carattere di EOF. Tuttavia non ho idea di superare questo problema. Data la grande dimensione del file combinati penso che è troppo ingombrante, per controllare ogni singolo carattere in ogni stringa. (Anche allora vorrei non essere ancora sicuro di cosa fare.) A quanto ho controllato, non ci sono caratteri strani nel file csv che potrebbero generare l’errore.
Ho provato anche il passaggio di error_bad_lines=False per pd.read_csv(), ma l’errore persiste.

Il mio codice è il seguente:

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

Modifica

Se vado in un file CSV che solleva la CParserError EOF… ed eliminare manualmente tutte le righe dopo la riga che causa il problema, il file csv viene letto correttamente. Comunque tutto sto cancellando sono righe vuote in ogni caso.
La cosa strana è che quando ho manualmente correggere l’erronea file csv, essi vengono caricati bene in negozio singolarmente. Ma quando ho di nuovo l’utilizzo di un elenco di file multipli il ‘falso’ i file sono ancora tornare dà errori.

  • non passare il mode='w'; si sono troncare il file hdf a ogni iterazione
  • si può provare a prendere il CParserError e saltare quel file (fino a risolvere il problema)
  • Ciao Jeff, come suggerisci prendo il CParserError. È troppo ingombrante per controllare ogni singolo file.
  • il primo a capire che file è, non controlla, basta prendere: from pandas.io import parser; try: your read_csv look for file f except (parser.CParserError) as detail: print f, detail
  • Mi dispiace non attirano il codice – io sono piuttosto nuovo a python/panda. Potresti spiegare un po ‘ di più per favore?
InformationsquelleAutor Matthijs | 2013-08-02

 

6 Replies
  1. 74

    Ho avuto un problema simile. La linea elencate con il ‘EOF all’interno della stringa’ era una stringa che conteneva al suo interno una sola virgoletta. Quando ho aggiunto l’opzione citando=csv.QUOTE_NONE risolto il mio problema.

    Per esempio:

    import csv
    df = pd.read_csv(csvfile, header = None, delimiter="\t", quoting=csv.QUOTE_NONE, encoding='utf-8')
    • questa è una soluzione ottimale
  2. 14

    Ho lo stesso problema, e dopo l’aggiunta di questi due parametri al mio codice, il problema è sparito.

    read_csv (…quoting=3, error_bad_lines=False)

    • Questo funziona come un fascino. C’è stato un errore in una riga. Dopo l’esecuzione con opzione di cui sopra ho ottenuto il seguente messaggio Skipping line 192: expected 5 fields, saw 74
  3. 5

    Rendere il vostro anello interno, come questo vi permetterà di rilevare il ‘cattivo’ di file (e indagare ulteriormente)

    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
    • Ciao Jeff, grazie! Funziona e mi ha fatto scoprire quali file/linee sono la causa del problema. Ora posso provare a ‘correggere’ i file manualmente, ma avrei preferito avere un più soluzione a livello di programmazione. Quindi ho bisogno di capire che cosa è in realtà l’errore mi viene restituito e che tipo di codice devo scrivere che automaticamente si prende cura di questo problema.
    • si potrebbe provare a specificare un lineterminator (che è essenzialmente \n su linux (o \n\r su windows mi pare). E peggio si ottiene una brutta linea (come le voci di terminator è messo in riga successiva)…..ma hanno bisogno di vedere cosa c’è di sbagliato in primo luogo: pandas.pydata.org/pandas-docs/dev/io.html#csv-text-files
    • La cosa strana è che quando ho manualmente correggere l’erronea file csv, essi vengono caricati bene in negozio singolarmente. Ma quando ho di nuovo l’uso glob a leggere un mucchio di file, questi file sono ancora tornare dà errori.
    • che è di strano su glob; io personalmente uso qualcosa di simile for f in os.listdir(dir); if is_ok(f): process_file(f), dove is_ok è una funzione di accettare/rifiutare il nome del file (o potrebbero essere altri criteri o un re.search
    • Grazie Jeff, cercherò qualcosa di simile. Anche io non riuscivo a specificare il lineterminator essere uguale a \n\r, la ricezione di un messaggio di errore che solo 1-lunghezza lineterminators può essere utilizzato (come sollevata anche qui github.com/pydata/pandas/issues/3501).
    • che, per definizione; si può semplicemente sostituire la linea endnding del file a un altro carattere; il file è danneggiato in qualche modo
    • su un lato nota, penso che la prima riga di codice è from pandas import parser invece di from pandas.io import parser? Come quest’ultimo non può funzionare con la mia panda 0.15.0

  4. 4

    Mi rendo conto che questa è una vecchia questione, ma volevo condividere qualche dettaglio in più sulla causa principale di questo errore e perché la soluzione da @Selah opere.

    Dal 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 è il valore di default e " è l’impostazione predefinita quotechar. Se da qualche parte nel file csv si dispone di un quotechar verrà analizzato come una stringa fino a quando un’altra ricorrenza del quotechar. Se il file ha un numero dispari di quotechars l’ultimo non verrà chiuso prima di raggiungere il EOF (end of file). Anche essere consapevoli che tutto tra il quotechars verrà analizzato come una singola stringa. Anche se ci sono molte interruzioni di riga (dovrebbe essere analizzato come righe separate) va tutto in un unico campo di tabella. Così il numero di riga che si ottiene il messaggio di errore può essere fuorviante. Per illustrare con un esempio, considerare questo:

    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

    La prima stringa è 2 (anche) quotechars. Così ogni quotechar è chiuso e il csv è analizzato senza un errore, anche se probabilmente non è quello che ci aspettavamo. La stringa di altri 3 (dispari) quotechars. Quest’ultimo non è chiuso e l’EOF è raggiunto quindi l’errore. Ma la linea 2 che si ottiene il messaggio di errore è fuorviante. Ci si aspetterebbe 4, ma dal momento che il tutto tra la prima e la seconda quotechar è analizzata come una stringa nostro "p,q,r linea è in realtà il secondo.

  5. 3

    La soluzione è usare il parametro del motore= “python” in read_csv funzione. La Panda CSV parser possibile utilizzare due diversi “motori” per analizzare un file CSV – Python o C (che è anche il default).

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

    Python motore è definito “più lento, ma è più completa” in Panda documentazione.

    engine : {‘c’, python’}
  6. 0

    Per me, altre soluzioni non ha funzionato e mi ha causato un bel mal di testa. error_bad_lines=False dà ancora l’errore C error: EOF inside string starting at line. Utilizzando un diverso citando non dare i risultati desiderati, perché non volevo avere preventivi nel mio testo.

    Ho capito che c’era un bug in Panda 0.20. L’aggiornamento alla versione 0.21 completamente risolto il mio problema. Ulteriori informazioni su questo problema, vedere: https://github.com/pandas-dev/pandas/issues/16559

    Nota: questo può essere relativi a Windows come indicato nell’URL.

    • Questo non funziona anche dopo l’aggiornamento di panda-0.22.0 ho ottenuto lo stesso errore

Lascia un commento