Panda Python Errore nella tokenizzazione dei dati


343

Sto provando a usare i panda per manipolare un file .csv ma ​​ottengo questo errore:

pandas.parser.CParserError: errore nella tokenizzazione dei dati. Errore C: previsti 2 campi nella riga 3, visto 12

Ho provato a leggere i documenti di Panda, ma non ho trovato nulla.

Il mio codice è semplice:

path = 'GOOG Key Ratios.csv'
#print(open(path).read())
data = pd.read_csv(path)

Come posso risolvere questo? Dovrei usare il csvmodulo o un'altra lingua?

Il file proviene da Morningstar


10
Se questo errore si verifica durante la lettura di un file scritto da pandas.to_csv(), POTREBBE essere perché c'è un '\ r' nei nomi di una colonna, nel qual caso to_csv () scriverà effettivamente i nomi delle colonne successive nella prima colonna del frame di dati, causando una differenza tra il numero di colonne nelle prime X righe. Questa differenza è una delle cause dell'errore C.
user0

9
A volte, solo dare esplicitamente il parametro "sep" aiuta. Sembra essere un problema di parser.
Gilgamash,

2
Questo errore può verificarsi anche quando si utilizza la virgola come delimitatore e si hanno più virgole del previsto (più campi nella riga dell'errore quindi definiti nell'intestazione). Quindi è necessario rimuovere il campo aggiuntivo o rimuovere la virgola aggiuntiva se è lì per errore. È possibile risolvere questo problema manualmente e quindi non è necessario saltare le righe di errore.
tsveti_iko,

2
Il commento di Gilgamash mi ha aiutato. Apri il file CSV in un editor di testo (come l'editor di Windows o il blocco note ++) in modo da vedere quale carattere viene utilizzato per la separazione. Se è un punto e virgola, ad esempio, prova pd.read_csv("<path>", sep=";"). Non utilizzare Excel per il controllo poiché a volte inserisce i dati in colonne per impostazione predefinita e quindi rimuove il separatore.
Giuliano

Per quanto riguarda il commento di @gilgamash, questo mi ha inviato nella giusta direzione, tuttavia nel mio caso è stato risolto non esplicitamente dando il parametro "sep".
TheLoneDeranger il

Risposte:


515

potresti anche provare;

data = pd.read_csv('file1.csv', error_bad_lines=False)

Si noti che ciò causerà il salto delle linee offensive.


152
Si noti che l'utilizzo di error_bad_lines = False provocherà il salto delle righe offensive.
biobirdman,

10
Inciampato su questa risposta, c'è un modo per riempire le colonne mancanti su righe che producono qualcosa di simile expected 8 fields, saw 9?
Petra Barus,

26
La soluzione migliore è investigare il file offensivo e correggere le righe errate in modo che possano essere lette da read_csv. @PetraBarus, perché non aggiungere semplicemente colonne ai file CSV che le mancano (con valori null secondo necessità)?
dbliss,

4
Sì, l'ho appena fatto. È molto più semplice aggiungendo colonne. L'apertura di CSV in un foglio di calcolo fa ciò.
Petra Barus,

5
Passando names=["col1", "col2", ...]per il numero massimo di colonne previste funziona anche, ed è così che ho risolto questo problema quando l'ho trovato. Vedi: stackoverflow.com/questions/18039057/...
Steven Rouk

100

Potrebbe essere un problema con

  • i delimitatori nei tuoi dati
  • la prima riga, come ha notato @TomAugspurger

Per risolverlo, prova a specificare gli argomenti sepe / o headerdurante la chiamata read_csv. Per esempio,

df = pandas.read_csv(fileName, sep='delimiter', header=None)

Nel codice sopra, sepdefinisce il delimitatore e header=Noneindica ai panda che i dati di origine non hanno righe per i titoli delle intestazioni / colonne. Così dice il documento : "Se il file non contiene righe di intestazione, allora dovresti passare esplicitamente header = None". In questo caso, i panda creano automaticamente indici di numeri interi per ciascun campo {0,1,2, ...}.

Secondo i documenti, la cosa delimitatore non dovrebbe essere un problema. I documenti dicono che "se sep è None [non specificato], proverà a determinarlo automaticamente." Tuttavia, non ho avuto fortuna con questo, compresi casi con delimitatori evidenti.


Sì, a volte il delimitatore può essere la causa di questo problema. Ho affrontato lo stesso problema in cui il delimitatore era un punto e virgola (;)
Anurag Sharma,

43

Il parser viene confuso dall'intestazione del file. Legge la prima riga e indica il numero di colonne da quella riga. Ma le prime due righe non sono rappresentative dei dati effettivi nel file.

Provalo con data = pd.read_csv(path, skiprows=2)


30

Il tuo file CSV potrebbe avere un numero variabile di colonne e read_csvdedotto il numero di colonne dalle prime poche righe. Due modi per risolverlo in questo caso:

1) Modificare il file CSV in modo che abbia una prima riga fittizia con il numero massimo di colonne (e specificare header=[0] )

2) Oppure usa names = list(range(0,N))dove N è il numero massimo di colonne.


25

Questo è sicuramente un problema del delimitatore, poiché la maggior parte del CSV CSV viene creata usando, sep='/t'quindi prova ad read_csvusare il carattere tab (\t)usando il separatore /t. quindi, prova ad aprire usando la seguente riga di codice.

data=pd.read_csv("File_path", sep='\t')

5
@MichaelQueue: questo non è corretto. Un CSV, sebbene comunemente delimitato da una virgola, può essere delimitato anche da altri caratteri. Vedi le specifiche CSV . Può essere una virgola, una scheda ('\ t'), punto e virgola e possibilmente spazi aggiuntivi. :)
DJGrandpaJ

nel mio caso era un problema di separazione. read_csv apparentemente utilizza le virgole e ho campi di testo che includono virgole (e comunque i dati sono stati memorizzati con un diverso separatore)
user108569

Se le virgole vengono utilizzate nei valori ma tab è il delimitatore e sep non viene utilizzato (o come suggerito sopra i delimitatori qualunque cosa si supponga si verifichi nei valori), si verificherà questo errore. Assicurati che il delimitatore non si presenti in nessuno dei valori, altrimenti alcune righe sembreranno avere il numero errato di colonne
demongolem

Sto usando Excel 2016 durante la creazione del CSV e usando sep = ';' lavoro per me
Abdullah ha detto il

18

Ho avuto anche questo problema, ma forse per un motivo diverso. Avevo alcune virgole finali nel mio CSV che stavano aggiungendo una colonna aggiuntiva che i panda stavano tentando di leggere. Usando le seguenti opere si ignora semplicemente le righe errate:

data = pd.read_csv('file1.csv', error_bad_lines=False)

Se vuoi mantenere le linee un brutto tipo di hack per gestire gli errori è fare qualcosa come il seguente:

line     = []
expected = []
saw      = []     
cont     = True 

while cont == True:     
    try:
        data = pd.read_csv('file1.csv',skiprows=line)
        cont = False
    except Exception as e:    
        errortype = e.message.split('.')[0].strip()                                
        if errortype == 'Error tokenizing data':                        
           cerror      = e.message.split(':')[1].strip().replace(',','')
           nums        = [n for n in cerror.split(' ') if str.isdigit(n)]
           expected.append(int(nums[0]))
           saw.append(int(nums[2]))
           line.append(int(nums[1])-1)
         else:
           cerror      = 'Unknown'
           print 'Unknown Error - 222'

if line != []:
    # Handle the errors however you want

Ho proceduto a scrivere uno script per reinserire le righe nel DataFrame poiché le righe errate verranno fornite dalla variabile 'line' nel codice sopra. Tutto ciò può essere evitato semplicemente usando il lettore CSV. Speriamo che gli sviluppatori di Panda possano rendere più semplice affrontare questa situazione in futuro.


14

Ho avuto questo problema, dove stavo cercando di leggere in un CSV senza passare i nomi delle colonne.

df = pd.read_csv(filename, header=None)

Ho precedentemente specificato i nomi delle colonne in un elenco, quindi li ho passati namese l'ho risolto immediatamente. Se non hai impostato i nomi delle colonne, puoi semplicemente creare tanti nomi segnaposto quanti sono il numero massimo di colonne che potrebbero essere nei tuoi dati.

col_names = ["col1", "col2", "col3", ...]
df = pd.read_csv(filename, names=col_names)

1
Questa risposta è migliore perché la riga non viene eliminata rispetto a se si utilizza error_bad_line = False. Inoltre, puoi facilmente capire quali linee erano quelle problematiche dopo aver creato un frame di dati da questa soluzione.
zipline86

Sono d'accordo con @ zipline86. Questa risposta è sicura e intelligente.
Monica Heddneck,

11

Ho avuto questo problema alcune volte da solo. Quasi ogni volta, la ragione è che il file che stavo tentando di aprire non era un CSV correttamente salvato all'inizio. E per "correttamente" intendo che ogni riga aveva lo stesso numero di separatori o colonne.

In genere è successo perché avevo aperto il CSV in Excel e l'avevo salvato in modo errato. Anche se l'estensione del file era ancora .csv, il formato CSV puro era stato modificato.

Qualsiasi file salvato con Panda to_csv sarà formattato correttamente e non dovrebbe avere questo problema. Ma se lo apri con un altro programma, potrebbe cambiare la struttura.

Spero che aiuti.


8

Mi sono imbattuto nello stesso problema. utilizzandopd.read_table() sullo stesso file di origine sembrava funzionare. Non sono riuscito a rintracciarne il motivo, ma è stata un'utile soluzione per il mio caso. Forse qualcuno più esperto può far luce sul perché ha funzionato.

Modifica: ho scoperto che questo errore si verifica quando hai del testo nel tuo file che non ha lo stesso formato dei dati effettivi. Di solito si tratta di informazioni di intestazione o piè di pagina (maggiore di una riga, quindi skip_header non funziona) che non saranno separati dallo stesso numero di virgole dei dati effettivi (quando si utilizza read_csv). L'uso di read_table utilizza una scheda come delimitatore che potrebbe eludere l'errore corrente dell'utente ma introdurne altri.

Di solito mi aggiro leggendo i dati extra in un file, quindi uso il metodo read_csv ().

La soluzione esatta potrebbe differire a seconda del file effettivo, ma questo approccio ha funzionato per me in diversi casi


6

Quanto segue ha funzionato per me (ho pubblicato questa risposta, perché ho avuto questo problema in particolare in un quaderno di Google Colaboratory):

df = pd.read_csv("/path/foo.csv", delimiter=';', skiprows=0, low_memory=False)

1
Ho sperimentato problemi quando non sono stato impostato |come delimitatore per il mio .csv. Preferisco provare prima questo approccio, invece di saltare le linee o le linee sbagliate.
Ivanleoncz,

Ho anche avuto lo stesso problema, supponevo che "\ t" sarebbe stato rilevato come delimitatore di default. Ha funzionato quando ho impostato esplicitamente il delimitatore su "\ t".
Rahul Jha,

5

Ho avuto un problema simile durante il tentativo di leggere una tabella delimitata da tabulazioni con spazi, virgole e virgolette:

1115794 4218    "k__Bacteria", "p__Firmicutes", "c__Bacilli", "o__Bacillales", "f__Bacillaceae", ""
1144102 3180    "k__Bacteria", "p__Firmicutes", "c__Bacilli", "o__Bacillales", "f__Bacillaceae", "g__Bacillus", ""
368444  2328    "k__Bacteria", "p__Bacteroidetes", "c__Bacteroidia", "o__Bacteroidales", "f__Bacteroidaceae", "g__Bacteroides", ""



import pandas as pd
# Same error for read_table
counts = pd.read_csv(path_counts, sep='\t', index_col=2, header=None, engine = 'c')

pandas.io.common.CParserError: Error tokenizing data. C error: out of memory

Questo dice che ha qualcosa a che fare con il motore di analisi C (che è quello predefinito). Forse cambiando in un pitone si cambierà qualcosa

counts = pd.read_table(path_counts, sep='\t', index_col=2, header=None, engine='python')

Segmentation fault (core dumped)

Questo è un errore diverso.
Se andiamo avanti e proviamo a rimuovere gli spazi dalla tabella, l'errore dal motore Python cambia ancora:

1115794 4218    "k__Bacteria","p__Firmicutes","c__Bacilli","o__Bacillales","f__Bacillaceae",""
1144102 3180    "k__Bacteria","p__Firmicutes","c__Bacilli","o__Bacillales","f__Bacillaceae","g__Bacillus",""
368444  2328    "k__Bacteria","p__Bacteroidetes","c__Bacteroidia","o__Bacteroidales","f__Bacteroidaceae","g__Bacteroides",""


_csv.Error: '   ' expected after '"'

E diventa chiaro che i panda avevano problemi ad analizzare le nostre file. Per analizzare una tabella con il motore Python avevo bisogno di rimuovere preventivamente tutti gli spazi e le virgolette dalla tabella. Nel frattempo il motore a C continuava a bloccarsi anche con le virgole nelle file.

Per evitare di creare un nuovo file con sostituzioni, l'ho fatto, poiché le mie tabelle sono piccole:

from io import StringIO
with open(path_counts) as f:
    input = StringIO(f.read().replace('", ""', '').replace('"', '').replace(', ', ',').replace('\0',''))
    counts = pd.read_table(input, sep='\t', index_col=2, header=None, engine='python')

tl; dr
Modifica il motore di analisi, cerca di evitare virgolette / virgole / spazi non delimitanti nei tuoi dati.


5

Il set di dati che ho usato aveva molte virgolette (") utilizzate in modo estraneo alla formattazione. Sono stato in grado di correggere l'errore includendo questo parametro per read_csv():

quoting=3 # 3 correlates to csv.QUOTE_NONE for pandas

2
inciampò nella stessa identica cosa. Per quanto mi riguarda, questa è la risposta corretta. Quello accettato nasconde l'errore.
LHK

Risposta corretta anche per me. +1
Taha Jirjees,

4

Usa delimitatore nel parametro

pd.read_csv(filename, delimiter=",", encoding='utf-8')

Leggerà.


3

Sebbene non sia il caso di questa domanda, questo errore può apparire anche con i dati compressi. Impostazione esplicita del valore per il kwarg compressionmio problema risolto.

result = pandas.read_csv(data_source, compression='gzip')

3

Un'alternativa che ho trovato utile per gestire simili errori di analisi utilizza il modulo CSV per reindirizzare i dati in un pandas df. Per esempio:

import csv
import pandas as pd
path = 'C:/FileLocation/'
file = 'filename.csv'
f = open(path+file,'rt')
reader = csv.reader(f)

#once contents are available, I then put them in a list
csv_list = []
for l in reader:
    csv_list.append(l)
f.close()
#now pandas has no problem getting into a df
df = pd.DataFrame(csv_list)

Trovo che il modulo CSV sia un po 'più robusto per i file separati da virgola mal formattati e quindi ho avuto successo con questo percorso per affrontare problemi come questi.


3

la seguente sequenza di comandi funziona (perdo la prima riga dei dati -no header = Nessuno presente-, ma almeno si carica):

df = pd.read_csv(filename, usecols=range(0, 42)) df.columns = ['YR', 'MO', 'DAY', 'HR', 'MIN', 'SEC', 'HUND', 'ERROR', 'RECTYPE', 'LANE', 'SPEED', 'CLASS', 'LENGTH', 'GVW', 'ESAL', 'W1', 'S1', 'W2', 'S2', 'W3', 'S3', 'W4', 'S4', 'W5', 'S5', 'W6', 'S6', 'W7', 'S7', 'W8', 'S8', 'W9', 'S9', 'W10', 'S10', 'W11', 'S11', 'W12', 'S12', 'W13', 'S13', 'W14']

Di seguito NON funziona:

df = pd.read_csv(filename, names=['YR', 'MO', 'DAY', 'HR', 'MIN', 'SEC', 'HUND', 'ERROR', 'RECTYPE', 'LANE', 'SPEED', 'CLASS', 'LENGTH', 'GVW', 'ESAL', 'W1', 'S1', 'W2', 'S2', 'W3', 'S3', 'W4', 'S4', 'W5', 'S5', 'W6', 'S6', 'W7', 'S7', 'W8', 'S8', 'W9', 'S9', 'W10', 'S10', 'W11', 'S11', 'W12', 'S12', 'W13', 'S13', 'W14'], usecols=range(0, 42))

CParserError: errore nella tokenizzazione dei dati. Errore C: previsti 53 campi nella riga 1605634, visto 54 I seguenti NON funzionano:

df = pd.read_csv(filename, header=None)

CParserError: errore nella tokenizzazione dei dati. Errore C: previsti 53 campi nella riga 1605634, visto 54

Quindi, nel tuo problema devi passare usecols=range(0, 2)


3

Per coloro che hanno problemi simili con Python 3 su SO Linux.

pandas.errors.ParserError: Error tokenizing data. C error: Calling
read(nbytes) on source failed. Try engine='python'.

Provare:

df.read_csv('file.csv', encoding='utf8', engine='python')

2

A volte il problema non è come usare Python, ma con i dati grezzi.
Ho ricevuto questo messaggio di errore

Error tokenizing data. C error: Expected 18 fields in line 72, saw 19.

Si è scoperto che nella descrizione della colonna c'erano talvolta delle virgole. Ciò significa che il file CSV deve essere pulito o utilizzato un altro separatore.



1

Avevo un set di dati con numeri di riga preesistenti, ho usato index_col:

pd.read_csv('train.csv', index_col=0)

1

Questo è quello che ho fatto.

sep='::' risolto il mio problema:

data=pd.read_csv('C:\\Users\\HP\\Downloads\\NPL ASSINGMENT 2 imdb_labelled\\imdb_labelled.txt',engine='python',header=None,sep='::')

1

Ho avuto un caso simile come questo e ambientazione

train = pd.read_csv('input.csv' , encoding='latin1',engine='python') 

lavorato


1

Ho lo stesso problema quando read_csv: ParserError: errore nella tokenizzazione dei dati. Ho appena salvato il vecchio file CSV in un nuovo file CSV. Il problema è risolto!


1

Il problema per me era che una nuova colonna veniva aggiunta al mio intraday CSV . La soluzione di risposta accettata non funzionerebbe poiché ogni riga futura verrebbe scartata se la usassi error_bad_lines=False.

La soluzione in questo caso era usare il parametro usecols in pd.read_csv(). In questo modo posso specificare solo le colonne che devo leggere nel CSV e il mio codice Python rimarrà resistente alle future modifiche CSV finché esiste una colonna di intestazione (e i nomi delle colonne non cambiano).

usecols : list-like or callable, optional 

Return a subset of the columns. If list-like, all elements must either
be positional (i.e. integer indices into the document columns) or
strings that correspond to column names provided either by the user in
names or inferred from the document header row(s). For example, a
valid list-like usecols parameter would be [0, 1, 2] or ['foo', 'bar',
'baz']. Element order is ignored, so usecols=[0, 1] is the same as [1,
0]. To instantiate a DataFrame from data with element order preserved
use pd.read_csv(data, usecols=['foo', 'bar'])[['foo', 'bar']] for
columns in ['foo', 'bar'] order or pd.read_csv(data, usecols=['foo',
'bar'])[['bar', 'foo']] for ['bar', 'foo'] order.

Esempio

my_columns = ['foo', 'bar', 'bob']
df = pd.read_csv(file_path, usecols=my_columns)

Un altro vantaggio di questo è che posso caricare molti meno dati in memoria se sto usando solo 3-4 colonne di un CSV che ha 18-20 colonne.


1

Risoluzione semplice : apri il file CSV in Excel e salvalo con un altro nome file in formato CSV. Prova di nuovo a importarlo spyder, il tuo problema verrà risolto!


1

Ho riscontrato questo errore con virgolette vaganti. Uso un software di mappatura che metterà le virgolette attorno agli elementi di testo durante l'esportazione di file delimitati da virgole. Il testo che utilizza le virgolette (ad es. '= Piedi e "= pollici) può essere problematico quando inducono collisioni del delimitatore. Considera questo esempio che nota che una stampa di tronchi da 5 pollici è scadente:

UWI_key,Latitude,Longitude,Remark US42051316890000,30.4386484,-96.4330734,"poor 5""

Usando 5"come scorciatoia si 5 inchfinisce per lanciare una chiave inglese nelle opere. Excel eliminerà semplicemente il segno di virgolette aggiuntivo, ma Panda si rompe senza l' error_bad_lines=Falseargomento sopra menzionato.


1

Per quanto ne so, e dopo aver dato un'occhiata al tuo file, il problema è che il file CSV che stai tentando di caricare ha più tabelle. Vi sono righe vuote o righe che contengono titoli di tabella. Prova a dare un'occhiata a questa risposta StackOverflow . Mostra come raggiungerlo a livello di codice.

Un altro approccio dinamico da fare sarebbe quello di utilizzare il modulo CSV , leggere ogni singola riga alla volta e fare controlli di integrità / espressioni regolari, per dedurre se la riga è (titolo / intestazione / valori / vuoto). Hai un ulteriore vantaggio con questo approccio, che puoi dividere / aggiungere / raccogliere i tuoi dati in oggetti Python come desiderato.

Il più semplice di tutti sarebbe usare la funzione panda pd.read_clipboard() dopo aver selezionato e copiato manualmente la tabella negli appunti, nel caso in cui è possibile aprire il CSV in Excel o qualcosa del genere.

Irrilevante :

Inoltre, irrilevante per il tuo problema, ma perché nessuno ne ha fatto menzione : ho avuto lo stesso problema durante il caricamento di alcuni set di dati come seeds_dataset.txtda UCI. Nel mio caso, l'errore si stava verificando perché alcuni separatori avevano più spazi bianchi di una scheda vera \t. Vedere la riga 3 di seguito, ad esempio

14.38   14.21   0.8951  5.386   3.312   2.462   4.956   1
14.69   14.49   0.8799  5.563   3.259   3.586   5.219   1
14.11   14.1    0.8911  5.42    3.302   2.7     5       1

Pertanto, utilizzare \t+nel modello di separazione anziché \t.

data = pd.read_csv(path, sep='\t+`, header=None)

1

Nel mio caso, è perché il formato della prima e delle ultime due righe del file CSV è diverso dal contenuto centrale del file.

Quindi quello che faccio è aprire il file CSV come stringa, analizzare il contenuto della stringa, quindi utilizzare read_csvper ottenere un frame di dati.

import io
import pandas as pd

file = open(f'{file_path}/{file_name}', 'r')
content = file.read()

# change new line character from '\r\n' to '\n'
lines = content.replace('\r', '').split('\n')

# Remove the first and last 2 lines of the file
# StringIO can be considered as a file stored in memory
df = pd.read_csv(StringIO("\n".join(lines[2:-2])), header=None)

1

Nel mio caso il separatore non era il predefinito "," ma Tab.

pd.read_csv(file_name.csv, sep='\\t',lineterminator='\\r', engine='python', header='infer')

Nota: "\ t" non ha funzionato come suggerito da alcune fonti. "\\ t" era richiesto.


0

Ho avuto un errore simile e il problema era che avevo alcune virgolette di escape nel mio file CSV e avevo bisogno di impostare il parametro escapechar in modo appropriato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.