2017-12-31 26 views
0

Ich bin neu bei Python und habe noch keine Optimierung vorgenommen. Ich versuche, eine Reihe von Dateien zu nehmen, die selbst schon ziemlich groß sind und sie zu einer großen Datei zusammenfassen, die wahrscheinlich nahe bei 50-100 GB liegen wird, wäre meine Vermutung. Mehr Speicher als ich auf jeden Fall habe. Ich habe den Code unten erhalten und es funktioniert gut für kleine Dateien. Wenn ich versuche, die tatsächlichen Dateien für meinen Anwendungsfall zu verwenden, wird mein Computer vollständig gesperrt.Was würde diesen Code, der einige flache Dateien kombiniert, schneller ausführen?

Ich verstehe, dass Pandas ist schnell. Ich vermute, dass Datenrahmen im Speicher gespeichert werden. Wenn das der Fall ist, dann ist das wahrscheinlich, was hier alles kaputt macht. Gibt es eine Art oder einen Mechanismus, der auf die Festplatte ausgelaufen ist oder möglicherweise in eine vorhandene Datei geschrieben wurde, anstatt zu versuchen, die ganze Sache in einem Datenrahmen zu halten, bevor sie auf die Festplatte geschrieben wird? Oder vielleicht eine andere Option, an die ich nicht gedacht habe?

+2

Dispense mit Pandas zusammen, wenn alles, was Sie es verwenden, ist zu csv des zu analysieren. Sie müssen sie wahrscheinlich überhaupt nicht analysieren, vielleicht überspringen Sie eine Überschrift ... –

Antwort

1

Hier ist eine Nicht-Pandas-Lösung, die nicht alles in den Speicher lädt. Ich habe es nicht getestet, aber es sollte funktionieren.

import os 

file_masks = ['fhv', 'green', 'yellow'] 


def combine_files(file_mask): 

    with open(os.path.join('TaxiDriveCombinedData', file_mask + '_trip_data.csv'),'w') as fout: 
     csvfiles = [] 
     for path, directories, files in os.walk('TaxiDriveData/'): 
      csvfiles.extend([os.path.join(path, fn) for fn in files if fn.startswith(file_mask)]) 

     for in_file in csvfiles: 
      with open(in_file,'r') as fin: 
       # f.next() # comment this out if you want to remove the headers 
       for line in fin: 
        fout.write(line) 


for m in file_masks: 
    combine_files(m) 
+0

Ausgezeichnet! Das hat geklappt und meine Maschine in den Testdateien nicht gesperrt. Ich werde es über den gesamten Datensatz ausführen. Wenn das funktioniert, werde ich dies als die Antwort markieren. –

0

Sie brauchen Python nicht, um das zu tun. Es gibt viele Werkzeuge in einem Linux-System, die Dateien verbinden können und optimiert sind oder Parameter haben, um dies sehr effizient zu tun:

Dies ist nicht die effizienteste Option, aber zum Beispiel :

cat input/*.csv > output/combined.csv 

Wenn Sie ein High-Performance-Python-Version möchte ich Ihnen empfehlen für Zeile die Dateien in Stücke zu lesen und zu schreiben, anstatt die Dateien Zeile zu lesen.

Ihr größtes Problem ist die I/O und Sie können dies optimieren, indem Sie größere Informationsblöcke von der Festplatte lesen und schreiben. Wenn Sie die optimale Größe Ihrer Festplatte und Ihres Dateisystems lesen und schreiben, werden Sie den Unterschied bemerken. Zum Beispiel ist eine gemeinsame Blockgröße für neuere HDDs 4096-Byte (4 KiB).

Sie können so etwas wie das folgende versuchen:

NEW_LINE = '\n' 

def read_in_chunks(f, chunksize=4096): 
    while True: 
     chunk = f.read(chunksize) 
     if not chunk: 
      break 
     yield chunk 

(...) 

fout = open('output.csv', 'w') 

for fname in files: 
    with open(fname) as fin: 
     buffer = '' 
     for chunk in read_in_chunks(fin): 
      buffer += chunk 
      lines, tmp_buffer = buffer.rsplit(NEW_LINE, 1) 
      lines += NEW_LINE # rsplit removes the last new-line char. I re-add it 
      fout.write(lines) 
      buffer = tmp_buffer 

fout.close() 
Verwandte Themen