2017-02-24 7 views
0

Ich versuche, Modellausgabedateien zu verketten, der Modelllauf wurde in 5 aufgeteilt und jede Ausgabe entspricht einem dieser Teilläufe, aufgrund der Art, wie die Software es ausgibt Beginnen Sie mit dem Umbenennen von 0 an jeder der Dateiausgaben. Ich schrieb einen Code zu:Speicherfehler Python große Datei Zeile für Zeile verarbeiten

1) Verketten Sie alle Ausgabedateien zusammen 2) bearbeiten Sie die zusammengeführte Datei um alle Zeitschritte neu zu kennzeichnen, beginnend bei 0 und um jeweils ein Inkrement ansteigend.

Das Ziel ist, dass ich diese einzelne Datei in einem Stück in meine Visualisierungssoftware laden kann, anstatt 5 verschiedene Fenster zu öffnen.

Bis jetzt wirft mein Code einen Speicherfehler aufgrund der großen Dateien, mit denen ich es zu tun habe.

Ich habe ein paar Ideen, wie ich versuchen könnte, es loszuwerden, aber ich bin mir nicht sicher, was funktioniert und/oder könnte die Dinge auf einen Crawl verlangsamen.

-Code bisher:

import os 
import time 

start_time = time.time() 

#create new txt file in smae folder as python script 

open("domain.txt","w").close() 


"""create concatenated document of all tecplot output files""" 
#look into file number 1 

for folder in range(1,6,1): 
    folder = str(folder) 
    for name in os.listdir(folder): 
     if "domain" in name: 
      with open(folder+'/'+name) as file_content_list: 
       start = "" 
       for line in file_content_list: 
        start = start + line# + '\n' 
       with open('domain.txt','a') as f: 
        f.write(start) 
       # print start 

#identify file with "domain" in name 
#extract contents 
#append to the end of the new document with "domain" in folder level above 
#once completed, add 1 to the file number previously searched and do again 
#keep going until no more files with a higher number exist 

""" replace the old timesteps with new timesteps """ 
#open folder named domain.txt 
#Look for lines: 
##ZONE T="0.000000000000e+00s", N=87715, E=173528, F=FEPOINT, ET=QUADRILATERAL 
##STRANDID=1, SOLUTIONTIME=0.000000000000e+00 
# if they are found edits them, otherwise copy the line without alteration 

with open("domain.txt", "r") as combined_output: 
    start = "" 
    start_timestep = 0 
    time_increment = 3.154e10 
    for line in combined_output: 
     if "ZONE" in line: 
      start = start + 'ZONE T="' + str(start_timestep) + 's", N=87715, E=173528, F=FEPOINT, ET=QUADRILATERAL' + '\n' 
     elif "STRANDID" in line: 
      start = start + 'STRANDID=1, SOLUTIONTIME=' + str(start_timestep) + '\n' 
      start_timestep = start_timestep + time_increment 
     else: 
      start = start + line 

    with open('domain_final.txt','w') as f: 
     f.write(start) 

end_time = time.time() 
print 'runtime : ', end_time-start_time 

os.remove("domain.txt") 

Bisher habe ich den Speicherfehler bei der Verkettung der Bühne. Zur Verbesserung der

Ich kann:

1) Versuchen Sie, und die Korrekturen auf dem Sprung zu tun, wie ich jede Datei lesen, aber da es schon ist andernfalls ein ganz man gehen durch Ich glaube nicht, dass viel machen würde eine Differenz andere als Rechenzeit

2) Legen Sie die ganze Datei als in einem Array und eine Funktion der Kontrollen machen und diese Funktion auf dem Array ausgeführt:

Etwas wie:

def do_correction(line): 
     if "ZONE" in line: 
      return 'ZONE T="' + str(start_timestep) + 's", N=87715, E=173528, F=FEPOINT, ET=QUADRILATERAL' + '\n' 
     elif "STRANDID" in line: 
      return 'STRANDID=1, SOLUTIONTIME=' + str(start_timestep) + '\n' 
     else: 
      return line 

3) behalte es so wie es ist und frage Python, ob es in diesem Stadium nicht genügend Speicher gibt und schreibe in die Datei. Weiß jemand, ob das möglich ist?

Vielen Dank für Ihre Hilfe

+1

Ich verstehe nicht, warum Sie nicht die Daten on the fly statt am Ende schreiben. Dies ist stream-kompatibel (Hinweis: es muss wegen der Verkettung von Strings ewig dauern). Sie müssen Ihren Code vollständig neu schreiben. –

+1

Öffnen Sie die Ausgabe auch vor Ihrer for-Schleife und schreiben Sie das Ergebnis für jede Zeile direkt in die Ausgabedatei. Sonst wird Ihre "Start" -Variable mit sehr großen Dateien explodieren. – MKesper

+0

Ich dachte, dass das Schreiben in eine Datei eine kostspielige Operation war, also wollte ich alles in einer Zeichenkette stapeln und diese Zeichenkette am Ende mit einer einzigen write() Anweisung schreiben.Aus Ihrem Kommentar entnehme ich, dass es schneller ist, eine f.write() in jeder Zeile zu haben. – Sorade

Antwort

2

Es ist nicht notwendig, den gesamten Inhalt jeder Datei in dem Speicher zu lesen, bevor Sie in die Ausgabedatei zu schreiben. Große Dateien verbrauchen nur möglicherweise verfügbaren Speicher.

Einfach Zeile für Zeile lesen und schreiben. Öffnen Sie die Ausgabedatei auch nur einmal ... und wählen Sie einen Namen, der nicht als Eingabedatei selbst behandelt wird, da sonst die Gefahr besteht, dass die Ausgabedatei auf sich selbst verkettet wird (noch kein Problem, aber möglicherweise auch Sie bearbeiten auch Dateien aus dem aktuellen Verzeichnis) - wenn sie geladen werden, wird nicht bereits der gesamte Speicher belegt.

Jetzt können Sie die Daten in einer zeilenorientierten Weise verarbeiten - modifizieren Sie sie einfach, bevor Sie in die Ausgabedatei schreiben.

Verwandte Themen