2016-04-28 5 views
1

Ich habe eine große csv-Datei mit 25 Spalten, die ich als Pandas Dataframe lesen möchte. Ich benutze pandas.read_csv(). Das Problem ist, dass einige Zeilen haben zusätzliche Spalten, so etwas wie das:Pandas CParserError: Fehler Tokening Daten

 col1 col2 stringColumn ... col25 
1  12  1  str1     3 
... 
33657 2  3  str4     6  4 3 #<- that line has a problem 
33658 1  32  blbla     #<-some columns have missing data too 

Wenn ich versuche, es zu lesen, erhalte ich die Fehler

CParserError: Error tokenizing data. C error: Expected 25 fields in line 33657, saw 28 

Das Problem tritt nicht auf, wenn die zusätzlichen Werte erscheinen in den ersten Reihen. Zum Beispiel, wenn ich hinzufügen, Werte in der dritten Reihe der gleichen Datei funktioniert es gut

#that example works: 
      col1 col2 stringColumn ... col25 
    1  12  1  str1     3 
    2  12  1  str1     3 
    3  12  1  str1     3  f 4 
    ... 
    33657 2  3  str4     6  4 3 #<- that line has a problem 
    33658 1  32  blbla     #<-some columns have missing data too 

Meine Vermutung ist, dass Pandas die ersten (n) Zeilen überprüft die Anzahl der Spalten, um zu bestimmen, und wenn Sie zusätzliche Spalten nach dass es ein Problem hat, es zu analysieren.

Überspringen der fehlerhaften Linien wie vorgeschlagen here ist keine Option, diese Zeilen enthalten wertvolle Informationen.

Kennt jemand einen Weg um dies?

+0

Wie erwarten Sie, dass diese Zeilen gespeichert und dargestellt werden? Zum Beispiel sind Sie nach 25 oder 28 Spalten? – EdChum

+0

Ich interessiere mich nur für etwa die Hälfte der 25 Spalten. Die Werte in der Extra-Spalte interessieren mich nicht. – Sininho

+0

Sind die Anzahl der Spalten festgelegt oder nicht? also ist es immer 28 – EdChum

Antwort

0

Da ich keine Antwort gefunden habe, die das Problem vollständig löst, hier ist meine Arbeit um: Ich fand heraus, dass explizite Übergabe der Spaltennamen mit der Option names=('col1', 'col2', 'stringColumn' ... 'column25', '', '', '') ermöglicht mir, die Datei zu lesen. Es zwingt mich, jede Spalte zu lesen und zu parsen, was nicht ideal ist, da ich nur ungefähr die Hälfte davon brauche, aber zumindest kann ich die Datei jetzt lesen. Ich kombiniere die Argumente names und usecols und funktioniert nicht, wenn jemand eine andere Lösung hat, würde ich mich freuen, es zu hören.

0

In meinem ersten Beitrag erwähnte ich nicht "error_bad_lines" = False in pandas.read_csv. Ich entschied, dass dies tatsächlich die angemessenere und elegantere Lösung ist. Ich fand diesen Beitrag sehr nützlich.

Can I redirect the stdout in python into some sort of string buffer?

Ich habe einen kleinen Twist, um den Code in der Antwort gezeigt.

import sys 
import re 
from cStringIO import StringIO 
import pandas as pd 

fake_csv = '''1,2,3\na,b,c\na,b,c\na,b,c,d,e\na,b,c\na,b,c,d,e\na,b,c\n''' #bad data 
fname = "fake.csv" 
old_stderr = sys.stderr 
sys.stderr = mystderr = StringIO() 

df1 = pd.read_csv(StringIO(fake_csv), 
        error_bad_lines=False) 

sys.stderr = old_stderr 
log = mystderr.getvalue() 
isnum = re.compile("\d+") 

lines_skipped_log = [ 
    isnum.findall(i) + [fname]\ 
    for i in log.split("\n") if isnum.search(i) 
     ] 

columns=["line_num","flds_expct","num_fields","file"] 
lines_skipped_log.insert(0,columns) 

Von dort können Sie alles tun können Sie mit lines_skipped_log wie Ausgabe csv möchten, erstellen Sie einen Datenrahmen usw.

Vielleicht haben Sie ein Verzeichnis von Dateien voll. Sie können eine Liste von Pandas-Datenrahmen aus jedem Protokoll erstellen und verketten. Von dort haben Sie ein Protokoll darüber, welche Zeilen übersprungen wurden und für welche Dateien Sie griffbereit sind (wörtlich!).