2012-11-15 8 views
6

Ich bin ziemlich neu zu Python und Programmierung im Allgemeinen, aber ich versuche, eine "gleitende Fenster" Berechnung über eine Tab-getrennte .TXT-Datei, die etwa 7 Millionen Zeilen mit Python enthält . Was ich mit sliding window meine, ist, dass es eine Berechnung über etwa 50.000 Zeilen ausführt, die Nummer meldet und dann ungefähr 10.000 Zeilen nach oben bewegt und die gleiche Berechnung über weitere 50.000 Zeilen durchführt. Ich habe die Berechnung und das "gleitende Fenster" richtig funktioniert und es läuft gut, wenn ich es auf einer kleinen Teilmenge meiner Daten teste. Wenn ich jedoch versuche, das Programm über meinen gesamten Datensatz auszuführen, ist es unglaublich langsam (ich habe es jetzt für ungefähr 40 Stunden laufen lassen). Die Mathematik ist ziemlich einfach, also denke ich nicht, dass es so lange dauern sollte.Verarbeitung einer großen .TXT-Datei in Python effizient

Die Art, wie ich gerade meine .txt-Datei lese, ist mit dem Modul csv.DictReader. Mein Code ist wie folgt:

file1='/Users/Shared/SmallSetbee.txt' 
newfile=open(file1, 'rb') 
reader=csv.DictReader((line.replace('\0','') for line in newfile), delimiter="\t") 

Ich glaube, dass dies ein Wörterbuch macht auf einmal aus allen 7 Millionen Zeilen, die ich denke bin der Grund, warum es nach unten, so viel für die größere Datei verlangsamt werden könnte.

Da ich nur daran interessiert bin, meine Berechnung über "Chunks" oder "Windows" von Daten gleichzeitig auszuführen, gibt es eine effizientere Methode, nur bestimmte Linien gleichzeitig einzulesen, die Berechnung durchzuführen und dann mit zu wiederholen ein neues spezifiziertes "Stück" oder "Fenster" von spezifizierten Linien?

+1

Dies macht kein Wörterbuch für alle Zeilen gleichzeitig. Es erstellt ein Wörterbuch für jede Zeile. Dies bedeutet, dass das von Ihnen gepostete Snippet nicht die Ursache für Ihre Leistungsprobleme ist. Vielleicht könnten Sie uns etwas mehr Code zeigen? –

+1

Ich vermute, dass Sie, wenn Sie Berechnungen über große Mengen von tabellenartigen Daten durchführen, Pandas betrachten sollten: http://pandas.pydata.org/pandas-docs/dev/io.html#iterating-through- files-chunk-by-chunk Alles, was du zu tun versuchst, wurde wahrscheinlich schon 1000 mal besser gemacht. – Iguananaut

+0

Sie werden diese Berechnung auf 696 "Windows" ausführen. Wie lange dauert es für ein einzelnes Fenster in einer 50k-Zeilendatei? –

Antwort

6

Eine collections.deque ist eine bestellte Sammlung von Artikeln, die eine maximale Größe annehmen können. Wenn Sie ein Element an einem Ende hinzufügen, fällt eines von dem anderen Ende. Das bedeutet, dass Sie, um über ein "Fenster" auf Ihrem CSV zu iterieren, nur weitere Zeilen zum deque hinzufügen müssen, und es wird fertig sein, bereits komplette zu verwerfen.

dq = collections.deque(maxlen=50000) 
with open(...) as csv_file: 
    reader = csv.DictReader((line.replace("\0", "") for line in csv_file), delimiter="\t") 

    # initial fill 
    for _ in range(50000): 
     dq.append(reader.next()) 

    # repeated compute 
    try: 
     while 1: 
      compute(dq) 
      for _ in range(10000): 
       dq.append(reader.next()) 
    except StopIteration: 
      compute(dq) 
+1

'try/except' sollte näher an' reader.next() 'liegen, um zu vermeiden versehentlich 'StopIteration' von' compute (dq) ' – jfs

3

Verwenden Sie keine csv.DictReader statt csv.reader verwenden. Das Erstellen eines Wörterbuchs für jede Zeile dauert länger als das Erstellen einer Liste für jede Zeile. Außerdem ist es geringfügig schneller, auf eine Liste durch einen Index zuzugreifen, als auf ein Wörterbuch mit einem Schlüssel zuzugreifen.

I zeitgesteuerte Iteration über eine 300.000 Zeile 4 Spalten CSV-Datei mit den beiden csv-Readern. csv.DictReader dauerte sieben mal länger als ein csv.reader.

Kombinieren Sie dies mit katrielalex's suggestion zu verwenden collections.deque und Sie sollten eine schöne Beschleunigung sehen.

Zusätzlich profile Ihren Code, um festzustellen, wo Sie die meiste Zeit verbringen.