2016-09-08 6 views
1

Ich habe eine große gzip Datei, die ich in einen Pandas Datenrahmen importieren möchte. Leider hat die Datei eine ungerade Anzahl von Spalten. Die Daten haben in etwa folgendes Format:ValueError: Importieren von Daten über Chunks in pandas.csv_reader()

.... Col_20: 25 Col_21: 23432 Col22: 639142 
.... Col_20: 25 Col_22: 25134 Col23: 243344 
.... Col_21: 75 Col_23: 79876 Col25: 634534 Col22: 5 Col24: 73453 
.... Col_20: 25 Col_21: 32425 Col23: 989423 
.... Col_20: 25 Col_21: 23424 Col22: 342421 Col23: 7 Col24: 13424 Col 25: 67 
.... Col_20: 95 Col_21: 32121 Col25: 111231 

Als Test habe ich versucht, dies:

import pandas as pd 
filename = `path/to/filename.gz` 

for chunk in pd.read_csv(filename, sep='\t', chunksize=10**5, engine='python'): 
    print(chunk) 

Hier ist der Fehler, den ich im Gegenzug:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/nfs/sw/python/python-3.5.1/lib/python3.5/site-packages/pandas/io/parsers.py", line 795, in __next__ 
    return self.get_chunk() 
    File "/nfs/sw/python/python-3.5.1/lib/python3.5/site-packages/pandas/io/parsers.py", line 836, in get_chunk 
    return self.read(nrows=size) 
    File "/nfs/sw/python/python-3.5.1/lib/python3.5/site-packages/pandas/io/parsers.py", line 815, in read 
    ret = self._engine.read(nrows) 
    File "/nfs/sw/python/python-3.5.1/lib/python3.5/site-packages/pandas/io/parsers.py", line 1761, in read 
    alldata = self._rows_to_cols(content) 
    File "/nfs/sw/python/python-3.5.1/lib/python3.5/site-packages/pandas/io/parsers.py", line 2166, in _rows_to_cols 
    raise ValueError(msg) 
ValueError: Expected 18 fields in line 28, saw 22 

Wie kann man eine zuteilen bestimmte Anzahl von Spalten für pandas.read_csv()?

+1

Ihr Problem ist, einige missformed csv's hat nichts damit zu tun, die Anzahl der Spalten vorzubelegen, Sie müssen ein zusätzliches Debugging durchführen, um die spezielle Datei und Zeile zu finden, die fehlerhaft ist, Sie sollten eine Verbindung zum csv oder ein kleines Beispiel, das den Fehler reproduziert, veröffentlichen – EdChum

+0

@EdChum Es ist nicht nur eine Zeile --- diese Datei hat praktisch jede Zeile so. Einige Zeilen können 20 Spalten haben, die nächsten 28. Was ist der richtige Weg? – ShanZhengYang

+0

Ich kann hypothetische Fragen nicht beantworten, ohne konkrete Daten zu sehen, posten Sie Ihre Daten sollten sie reguläre Trennzeichen und Formular haben, wenn nicht, dann müssen Sie die Daten zuerst reinigen – EdChum

Antwort

1

Sie konnten dieses versuchen:

for chunk in pd.read_csv(filename, sep='\t', chunksize=10**5, engine='python', error_bad_lines=False): 
print(chunk) 

error_bad_lines würde überspringen dachte schlechte Linien. Ich werde sehen, ob eine bessere Alternative kann

EDIT gefunden werden: Um die Linien zu halten, die von error_bad_lines übersprungen wurden wir durch den Fehler gehen und fügen Sie es zurück an den Datenrahmen

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

Danke für die Hilfe. Ja, ich denke 'error_bad_lines' entfernt Daten, die ich dringend brauche ... – ShanZhengYang

+0

Ich habe einen schmutzigen Hack gefunden, lassen Sie mich die Antwort bearbeiten, ist vielleicht nicht ideal, sollte aber den Trick machen. – SerialDev

+1

Das Problem ist, dass es sehr schwierig wird, große Datenrahmen in der GB-Skala zu behandeln. Danke, das ist genial. – ShanZhengYang