2017-08-18 6 views
2

Ich versuche eine txt-Datei, die als unterschiedliche Anzahl von Spalten pro Zeile lesen. Hier ist der Anfang meiner Datei:ParserError mit Panda read_csv

60381 6 
1 0.270 0.30 0.30 0.70 0.70 
4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 
2 0.078 0.30 0.30 0.70 0.70 
5.387 5.312 5.338 4.463 4.675 4.275 4.238 3.562 3.175 3.925 4.950 4.762 
6 0.241 0.30 0.60 0.70 0.40 
3.700 3.200 2.738 2.325 1.250 0.975 1.175 1.950 2.488 3.613 3.987 3.950 
7 0.357 0.30 0.60 0.70 0.40 
1.212 1.125 1.050 0.950 0.663 0.488 0.425 0.512 0.637 0.900 1.112 1.188 
8 0.031 0.30 0.70 0.70 0.30 
0.225 0.213 0.200 0.175 0.200 0.213 0.375 0.887 0.975 0.512 0.262 0.262 
10 0.022 0.30 0.80 0.70 0.20 
0.712 0.700 0.738 0.550 0.513 0.688 0.613 0.600 0.850 0.812 0.800 0.775 
60382 5 
6 0.197 0.30 0.60 0.70 0.40 
3.700 3.200 2.738 2.325 1.250 0.975 1.175 1.950 2.488 3.613 3.987 3.950 
7 0.413 0.30 0.60 0.70 0.40 
1.212 1.125 1.050 0.950 0.663 0.488 0.425 0.512 0.637 0.900 1.112 1.188 
8 0.016 0.30 0.70 0.70 0.30 
0.225 0.213 0.200 0.175 0.200 0.213 0.375 0.887 0.975 0.512 0.262 0.262 
10 0.111 0.30 0.80 0.70 0.20 
0.712 0.700 0.738 0.550 0.513 0.688 0.613 0.600 0.850 0.812 0.800 0.775 
11 0.263 0.30 0.50 0.70 0.50 
1.812 1.388 1.087 0.825 0.538 0.400 0.338 0.400 0.500 0.925 0.962 1.100 

Ich habe versucht Pandas mit read_csv es zu lesen:

import pandas as pd 
data = pd.read_csv('./myfile.txt',header=None,sep='\s') 

Welche der folgenden Fehler gibt:

ParserError: Expected 6 fields in line 3, saw 12. Error could possibly be due to quotes being ignored when a multi-char delimiter is used. 

Also meine Datei doesn‘ t haben ein mehrzeiliges Trennzeichen oder Anführungszeichen. Ich habe eine Lösung für dieses ich in diesem Forum gefunden versucht, die Verwendung vorgeschlagen:

data = pd.read_csv(open('./myfile.txt','r'), header=None,encoding='utf-8', engine='c') 

Obwohl dies über den Fehler behebt, das Array ich vorgestellt habe nicht Raum als Trennzeichen von Spalten verwenden, und der Ausgang hat nur 1 Spalte:

data output

Wie soll ich die Datei lesen, um eine Spalte für jeden Wert zu erhalten? Es macht mir nichts aus, wenn es Nan-Werte gibt, die den Rest füllen.

+0

'" das Array, das mir präsentiert wird, verwendet kein Leerzeichen als Trennzeichen für Spalten "' Warum würde es? Sie haben 'read_csv' nie gesagt, dass die Datei Leerzeichen als Trennzeichen verwendet. Sie müssen 'delimiter = ''' an 'read_csv' übergeben. – DeepSpace

+1

Die Zeilen mit zwei Elementen (z. B. '60381 6') scheinen mir Metadaten zu sein. Sind Sie sicher, dass es sich um eine Standard-CSV-Datei handelt? – ayhan

+0

Vereinbaren Sie mit @ayhan - das ist, was das wirft – kbball

Antwort

1

Wenn Sie die Daten in einer einzigen Spalte erhalten haben, können Sie dieses Problem umgehen, indem Sie Series.str.split() verwenden. Hier

ist ein Beispiel mit einigen Beispieldaten Ihnen zur Verfügung gestellten (Sie beliebige Zeichenfolge oder einen regulären Ausdruck als Trennzeichen in split() verwenden):

df[0].str.split(' ', expand=True) 

    0  1  2  3  4  5  6  7  8  9 \ 
0 0.270 0.30 0.30 0.70 0.70 None None None None None 
1 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 

Wenn Sie dies tun, dann könnten Sie auch erstellen, den Datenrahmen mit pd.DataFrame(open(...).readlines()) oder etwas ähnliches, da Sie überhaupt nicht von read_csv() profitieren, und Ihre Datei ist nicht genau eine Standard-CSV-Datei.

# f is a StringIO with some of your sample data to simulate a file 
df = pd.DataFrame(line.strip().split(' ') for line in f) 

     0  1  2  3  4  5  6  7  8  9 \ 
0 60381  6 None None None None None None None None 
1  1 0.270 0.30 0.30 0.70 0.70 None None None None 
2 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 
3  2 0.078 0.30 0.30 0.70 0.70 None None None None 
4 5.387 5.312 5.338 4.463 4.675 4.275 4.238 3.562 3.175 3.925 

Natürlich können Sie auch die Eingabedatei beheben, indem Sie sicherstellen, dass jede Zeile die gleiche Anzahl von Spalten enthält, die die ParserError Problem lösen wird.

0

Erwägen Wiederaufbau iterativ die Textdatei und dann pd.read_table() auf gereinigten Textversion:

from io import StringIO 

txt=""" 
60381 6 
1 0.270 0.30 0.30 0.70 0.70 
4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 
2 0.078 0.30 0.30 0.70 0.70 
5.387 5.312 5.338 4.463 4.675 4.275 4.238 3.562 3.175 3.925 4.950 4.762 
6 0.241 0.30 0.60 0.70 0.40 
3.700 3.200 2.738 2.325 1.250 0.975 1.175 1.950 2.488 3.613 3.987 3.950 
7 0.357 0.30 0.60 0.70 0.40 
1.212 1.125 1.050 0.950 0.663 0.488 0.425 0.512 0.637 0.900 1.112 1.188 
8 0.031 0.30 0.70 0.70 0.30 
0.225 0.213 0.200 0.175 0.200 0.213 0.375 0.887 0.975 0.512 0.262 0.262 
10 0.022 0.30 0.80 0.70 0.20 
0.712 0.700 0.738 0.550 0.513 0.688 0.613 0.600 0.850 0.812 0.800 0.775 
60382 5 
6 0.197 0.30 0.60 0.70 0.40 
3.700 3.200 2.738 2.325 1.250 0.975 1.175 1.950 2.488 3.613 3.987 3.950 
7 0.413 0.30 0.60 0.70 0.40 
1.212 1.125 1.050 0.950 0.663 0.488 0.425 0.512 0.637 0.900 1.112 1.188 
8 0.016 0.30 0.70 0.70 0.30 
0.225 0.213 0.200 0.175 0.200 0.213 0.375 0.887 0.975 0.512 0.262 0.262 
10 0.111 0.30 0.80 0.70 0.20 
0.712 0.700 0.738 0.550 0.513 0.688 0.613 0.600 0.850 0.812 0.800 0.775 
11 0.263 0.30 0.50 0.70 0.50 
1.812 1.388 1.087 0.825 0.538 0.400 0.338 0.400 0.500 0.925 0.962 1.100 
""" 

for line in StringIO(txt): 

    if len(line) == 8: 
     header = line 
     next 
    if len(line) == 28 or len(line) == 29: 
     firstdata = line 
     next 
    if len(line) == 72: 
     seconddata = header + ' ' + firstdata + ' ' + line 
     print(seconddata.replace("\n", "")) 

Ausgabe

# 60381 6 1 0.270 0.30 0.30 0.70 0.70 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 4.988 
# 60381 6 2 0.078 0.30 0.30 0.70 0.70 5.387 5.312 5.338 4.463 4.675 4.275 4.238 3.562 3.175 3.925 4.950 4.762 
# 60381 6 6 0.241 0.30 0.60 0.70 0.40 3.700 3.200 2.738 2.325 1.250 0.975 1.175 1.950 2.488 3.613 3.987 3.950 
# 60381 6 7 0.357 0.30 0.60 0.70 0.40 1.212 1.125 1.050 0.950 0.663 0.488 0.425 0.512 0.637 0.900 1.112 1.188 
# 60381 6 8 0.031 0.30 0.70 0.70 0.30 0.225 0.213 0.200 0.175 0.200 0.213 0.375 0.887 0.975 0.512 0.262 0.262 
# 60381 6 10 0.022 0.30 0.80 0.70 0.20 0.712 0.700 0.738 0.550 0.513 0.688 0.613 0.600 0.850 0.812 0.800 0.775 
# 60382 5 6 0.197 0.30 0.60 0.70 0.40 3.700 3.200 2.738 2.325 1.250 0.975 1.175 1.950 2.488 3.613 3.987 3.950 
# 60382 5 7 0.413 0.30 0.60 0.70 0.40 1.212 1.125 1.050 0.950 0.663 0.488 0.425 0.512 0.637 0.900 1.112 1.188 
# 60382 5 8 0.016 0.30 0.70 0.70 0.30 0.225 0.213 0.200 0.175 0.200 0.213 0.375 0.887 0.975 0.512 0.262 0.262 
# 60382 5 10 0.111 0.30 0.80 0.70 0.20 0.712 0.700 0.738 0.550 0.513 0.688 0.613 0.600 0.850 0.812 0.800 0.775 
# 60382 5 11 0.263 0.30 0.50 0.70 0.50 1.812 1.388 1.087 0.825 0.538 0.400 0.338 0.400 0.500 0.925 0.962 1.100 

Jetzt für den Dateiimport in Pandas, sollten neue Ausgabe in eine Textdatei zu schreiben:

with open('input.txt', 'r') as f1, open('output.txt', 'w') as f2: 
    for line in f1: 
     if len(line) == 8: 
      header = line 
      next 
     if len(line) == 28 or len(line) == 29: 
      firstdata = line 
      next 
     if len(line) == 72: 
      seconddata = header + ' ' + firstdata + ' ' + line 
      f2.write(seconddata.replace("\n", "")) 

df = read.table('output.txt', header=None, sep="\\s+") 
+0

Dies erzeugt eine Datei mit nur 1 Zeile und einer Spalte pro Wert. Es fehlen auch einige Daten, da nicht alle Header den gleichen Betrag haben, wenn ** Firstada ** und ** Seconddata **. – lanadaquenada