2016-08-02 10 views
0

Wir stecken fest, einen Weg zu finden, eine knifflige Textdatei zu analysieren, die von einer PEST-Analyse mit Python erzeugt wird. Es zeigt Messungen von 63 verschiedenen Variablen für mehr als 30.000 Beobachtungen. Hier ist ein Beispiel für die Ausgabe (3 /> 30.000 gezeigt)Python parsen txt-Datei, PEST-Ausgabe, jacobian.txt

      cmfa   cmfb   cmfc   cmfd   cmla   cmlb   cmlc   cmld 
          cmle   cgfa   cgfb   cgfc   cgfd   cgfe   dgfa   dgfb 
          dgfc   dgfd   icfa   icfb   icfc   icfd   vawa   vawb 
          vawc   vawd   vawe   vawf   vswa   vswb   vswc   vswd 
          vswe   chfa   chfb   chfc   chfd   chfe   cgwa   cgwb 
          cgwc   cgwd   cgwe   crta   crtb   crtc   crtd   crte 
          icha   ichb   ichc   ichd   iche   csea   cseb   csec 
          csed   csee   csef   caqa   caqb   crsa   crsb 

       0 -1.900000E-03 1.080000E-02 3.150000E-02 0.00000  0.00000  0.00000  0.00000  -3.020000E-02 
         0.00000  -1.870000E-02 0.00000  4.600000E-03 0.00000  0.00000  0.00000  4.510000E-02 
         0.00000  0.00000  3.650000E-02 -7.000000E-03 -2.100000E-03 -2.000000E-04 3.200000E-03 8.000000E-03 
        -7.000000E-04 -1.500000E-02 0.00000  4.800000E-03 1.900000E-03 4.000000E-04 2.500000E-03 2.500000E-03 
        -1.400000E-02 0.00000  0.00000  0.00000  0.00000  0.00000  -3.200000E-03 -8.060000E-02 
        -0.126500  0.298400  0.00000  0.00000  0.00000  0.00000  0.00000  8.000000E-04 
        -1.900000E-03 1.400000E-03 0.00000  0.00000  -3.200000E-03 0.00000  0.00000  0.00000  
         0.00000  0.00000  0.00000  0.00000  0.00000  -1.200000E-02 1.930000E-02 

       1 -1.800000E-03 1.140000E-02 1.850000E-02 0.00000  0.00000  0.00000  0.00000  -2.600000E-02 
         0.00000  -8.200000E-03 0.00000  1.200000E-03 0.00000  0.00000  0.00000  0.00000  
         0.00000  0.00000  2.560000E-02 -6.100000E-03 -1.100000E-03 0.00000  3.000000E-03 7.400000E-03 
        -7.000000E-04 -1.410000E-02 0.00000  5.000000E-03 1.900000E-03 3.000000E-04 2.300000E-03 2.300000E-03 
        -1.330000E-02 0.00000  0.00000  0.00000  0.00000  0.00000  -3.400000E-03 -8.410000E-02 
        -0.123500  0.301900  0.00000  0.00000  0.00000  0.00000  0.00000  1.200000E-03 
        -2.000000E-03 1.400000E-03 0.00000  0.00000  -3.200000E-03 0.00000  0.00000  0.00000  
         0.00000  0.00000  0.00000  0.00000  0.00000  -1.280000E-02 2.050000E-02 

       2 -3.300000E-03 6.500000E-03 4.040000E-02 0.00000  0.00000  0.00000  0.00000  -7.060000E-02 
        4.840000E-02 -0.112500  0.110300  0.00000  0.00000  0.00000  1.10330  0.00000  
         0.00000  0.00000  3.940000E-02 -8.500000E-03 -1.120000E-02 6.600000E-03 5.700000E-03 1.430000E-02 
        -1.300000E-03 -2.470000E-02 0.00000  3.700000E-03 2.200000E-03 5.000000E-04 4.300000E-03 4.500000E-03 
        -2.250000E-02 0.00000  0.00000  0.00000  0.00000  0.00000  -2.000000E-03 -5.840000E-02 
        -0.157300  0.292400  0.00000  0.00000  0.00000  0.00000  0.00000  -3.600000E-03 
        -1.700000E-03 1.200000E-03 0.00000  0.00000  -3.400000E-03 0.00000  0.00000  0.00000  
         0.00000  0.00000  0.00000  0.00000  0.00000  -7.400000E-03 1.180000E-02 

       3 -2.200000E-03 1.040000E-02 3.500000E-02 0.00000  0.00000  0.00000  0.00000  -4.390000E-02 
         0.00000  -3.170000E-02 2.590000E-02 0.00000  0.00000  0.00000  0.259400  0.00000  
         0.00000  0.00000  3.920000E-02 -1.030000E-02 -3.500000E-03 1.500000E-03 3.600000E-03 9.000000E-03 
        -9.000000E-04 -1.680000E-02 0.00000  4.700000E-03 2.000000E-03 3.000000E-04 2.700000E-03 2.800000E-03 
        -1.560000E-02 0.00000  0.00000  0.00000  0.00000  0.00000  -3.200000E-03 -7.920000E-02 
        -0.131600  0.302200  0.00000  0.00000  0.00000  0.00000  0.00000  3.000000E-04 
        -2.000000E-03 1.300000E-03 0.00000  0.00000  -3.300000E-03 0.00000  0.00000  0.00000  
         0.00000  0.00000  0.00000  0.00000  0.00000  -1.180000E-02 1.880000E-02 

Die Buchstabencodes (OHFW, AWFZ, etc.) sind die Namen der 63 Variablen. Jede der Buchstabencodevariablen bezieht sich auf die Zahl an der gleichen Stelle für jeden der folgenden Textblöcke.

Der erste Zahlenblock ist für Beobachtung 0, der nächste Block für Beobachtung 1 usw. für mehr als 30.000 Beobachtungen.

Wir wollen einen Weg finden, um dies in eine Textdatei (vorzugsweise .csv) zu verwandeln. Im Fall meines Textbeispiels hätte es 63 Spalten und 3 Zeilen (+1 für den Bezeichner). Jede Spalte würde mit dem entsprechenden Buchstaben-Code betitelt werden (OHFW usw.)

Wenn möglich, würden wir dies gerne auf eine Datei mit einer beliebigen Anzahl von Spalten und einer beliebigen Anzahl von Beobachtungen

+0

Was haben Sie bisher versuchen? Eine einfache Lösung: Sie können einen Textprozessor mit regulären Ausdrücken wie vi (unix) oder notepad ++ (win) verwenden und einzelne Zeilenumbrüche in Leerzeichen oder Tabulatoren ersetzen, anstatt Leerzeichen oder Tabulatoren durch Kommas zu ersetzen. –

Antwort

1

einen Weg laufen das analysieren Datei, die Sie zur Verfügung gestellt haben (unabhängig von der Anzahl der Zeilen in der Datei) mit einfachen python kann eine bessere Implementierungen mit regulären Ausdrücken tun, aber ich würde es lassen Sie weiter, um zu versuchen:

#Importing required libraries 
import numpy as np 
import csv 

#Open input file 
with open('input.txt','rb') as f: 
    line = f.read().splitlines() 

#Read file and do some parsing 
line2 = [] 
for l in line: 
    z = l.split(" ") 
    l2 = [] 
    for val in z: 
     if not(val==''): 
      l2.append(val) 
    if len(l2)==9: 
     line2.append(l2[1:9]) 
    elif len(l2)==7 or len(l2)==8: 
     line2.append(l2) 

#Remove unnecessary rows and do type conversion to float 
pl = np.arange(0,len(line2)+1,8) 
line3 = [] 
for i in np.arange(0,len(pl)-1): 
    z = line2[pl[i]:pl[i+1]] 
    z2 = [item for sublist in z for item in sublist] 
    if i==0: 
     line3.append(z2) 
    else: 
     line3.append([float(i) for i in z2]) 

#Write to output file 
with open('output.csv','wb') as f: 
    wr = csv.writer(f) 
    for row in line3: 
     wr.writerow(row) 

Falls Sie behalten möchten die Indizes:

#Importing required libraries 
import numpy as np 
import csv 

#Open input file 
with open('input.txt','rb') as f: 
    line = f.read().splitlines() 

#Read file and do some parsing 
line2 = [] 
for l in line: 
    z = l.split(" ") 
    l2 = [] 
    for val in z: 
     if not(val==''): 
      l2.append(val) 
    if not(len(l2)==0): 
     line2.append(l2) 

#Remove unnecessary rows and do type conversion to float 
pl = np.arange(0,len(line2)+1,8) 
line3 = [] 
for i in np.arange(0,len(pl)-1): 
    if i==0: 
     z = line2[pl[i]:pl[i+1]] 
     z2 = [item for sublist in z for item in sublist] 
     line3.append(['']+z2) 
    else: 
     z = line2[pl[i]:pl[i+1]] 
     z2 = [item for sublist in z for item in sublist] 
     line3.append([float(i) for i in z2]) 

#Write to output file 
with open('output.csv','wb') as f: 
    wr = csv.writer(f) 
    for row in line3: 
     wr.writerow(row) 
+0

Danke Gaurav! Dies macht genau das, wonach ich gefragt hatte. Ich habe vergessen zu fragen, ob die Beobachtungsnummer auch als erste Spalte in der CSV (in diesem Fall 0,1,2,3) transkribiert werden könnte. Wäre es möglich, das auch im CSV zu haben? – bigCow

+0

Bearbeitet mit Obs Nummer enthalten. Prost!! Bitte markieren Sie als richtig, wenn Sie denken, dass das in Ordnung ist. –

+0

Wieder haben Sie genau das beantwortet, was ich gefragt habe. Mein Fehler, ich habe vergessen zu fragen, ob es auch möglich ist, das neue ID-Feld als 'ID' oder 'FID' oder so ähnlich zu benennen – bigCow

0

Sie können eine mmap und eine Regex verwenden, um die Datei zu analysieren, ohne dass Sie die gesamte Datei in den Speicher einlesen müssen.

Etwas wie:

import re 
import mmap 
import os 

size=os.stat(fn_in).st_size 

with open(fn_in, "r") as fin, open(fn_out, "w") as fout: 
    data = mmap.mmap(fin.fileno(), size, access=mmap.ACCESS_READ) 
    for idx, m in enumerate(re.finditer(r"(.*?)(?:(?:^\s*$)|\Z)", data, re.M | re.S)): 
     block=m.group(0).strip() 
     if not block: 
      continue 
     if idx==0: 
      fout.write("O_N,"+",".join(block.split())+"\n") 
     else: 
      fout.write(",".join(block.split())+"\n")