Operationen auf großer txt

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Crunkrock
User
Beiträge: 5
Registriert: Montag 22. August 2011, 14:02

Hallo,

ohne genauer auf den Inhalt meines tuns eingehen zu wollen, hab ich eine große Textdatei, die zeilenweise getrennten Inhalt hat, der in sich wiederum mehrfach durch Tabs getrennt ist, immer mit demselben Schema, im Grunde also eine Art Tabelle.

Ich will eine bestimmte Anzahl Zeilen einlesen, möglicherweise nicht immer von Anfang der Datei sondern zb von Zeile X bis Zeile Y, nach Tabs splitten, so dass ich mit den Informationen aus den einzelnen Spalten arbeiten kann, diverse Berechnungen mit diesen Informationen durchführen, das Ergebnis in eine andere Textdatei schreiben, und zur nächsten Zeile weitergehen.

Momentan iteriere ich mir einer for-Schleife über die Textdatei, splitte die Zeile nach Tabs in eine Liste, mit den Elementen die ich benötige führe ich meine Berechnungen durch, und schreib das Ergebnis in eine andere Textdatei. Hier scheitere ich schon, da offenbar alles im Speicher bleibt, nach 139 Zeilen hört der Rechner auf einzulesen, allerdings ohne Fehlermeldung, er führt danach kommende Schritte trotzdem aus. Auf dem Unirechner mit 256MB Ram klappt es wunderbar mit allen Zeilen.

Meine Frage: Welche Optimierungen oder ggf. andere Datenstrukturen würdet ihr mir empfehlen, um mit der großen txt umzugehen?
Benutzeravatar
pillmuncher
User
Beiträge: 1482
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Verwende eine Generator Expression:

Code: Alles auswählen

import csv

source_filename = ...
target_filename = ...

with open(source_filename, 'r') as source:
    with open(target_filename, 'w') as target:
        target.writelines(
            make_line_from(record) + '\n'
                for lineno, record in enumerate(csv.reader(source, delimiter='\t'))
                    if some_condition(record, lineno)
        )

def make_line_from(record):
    return ...

def some_condition(record, lineno):
    return ...
Du musst nur noch die ... ausprogrammieren.
Zuletzt geändert von pillmuncher am Dienstag 3. Juli 2012, 06:59, insgesamt 1-mal geändert.
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Hier scheitere ich schon, da offenbar alles im Speicher bleibt, nach 139 Zeilen hört der Rechner auf einzulesen,
139 Zeilen ist aber wenig, wenn du "nur" mir Text arbeitest. Selbst wenn die Zeilen lang wären sind das nicht viele Bytes, so dass selbst bei sehr wenig RAM der Speicher bei weitem nicht voll sein dürfte...

Zeig' doch mal deinen Code und ein paar Beispielzeilen aus der Text-Datei. :-)

Gruß, noisefloor
BlackJack

@Crunkrock: Weitermachen ohne weiter einzulesen? Wie soll dass den funktionieren? Kann es sein, dass die Fehlerbehandlung im Skript kaputt ist, und zum Beispiel so etwas wie `MemoryError` in nackten ``except:``-Blöcken einfach ignoriert wird? Behandle nur Ausnahmen von denen Du weisst warum sie an der jeweiligen Stelle ausgelöst werden können und auch dann nur wenn Du sie an der Stelle *sinnvoll* behandeln kannst. Einfach ignorieren ist in der Regel keine *sinvolle* Behandlung und ich versuche zum Beispiel bei so etwas immer einen Kommentar in den Quelltext zu schreiben *warum* eine bestimmte Ausnahme ignoriert werden kann, ohne das etwas Böses™ passiert.

Die Zahlen kommen mir auch komisch vor. Nach 139 Zeilen ist Schluss? Aber auf einem Rechner mit mickerigen 256 MB Arbeitsspeicher läuft es mit allen Zeilen durch? Wie viel, oder besser wie wenig, Arbeitsspeicher hat denn dann der Rechner bei dem nur 139 Zeilen verarbeitet werden?

Nicht alles in den Speicher lesen wurde ja schon genannt. Neben Generator-Ausdrücken hat das `itertools`-Modul noch einige interessante Werkzeuge. Zum Beispiel die `islice()`-Funktion um von einem iterierbaren Objekt nur die Elemente von ”Index” X bis Y zu verarbeiten.
Antworten