große txt-Datei teilweise auslesen

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
techma
User
Beiträge: 8
Registriert: Montag 9. Januar 2012, 07:56

Guten Morgen,

Ich muss eine große .txt Datei auslesen (2Gb). Komplett einlesen funktioniert nicht, da der Arbeitsspeicher nicht ausreicht.

Die txt Datei hat 51 Blöcke mit jeweils gleicher Zeilenanzahl. Ich möchte die Datei nun für jeden Block auslesen z.B. beginnt der erste Block bei Zeile 18 und endet in Zeile 302424.
Mit readlines() kann man nur die bytes angeben, die gelesen werden sollen; ich benötige einen Befehl mit dem ich angeben kann von wo bis wo die Datei ausgelesen werden soll.

hat jemand eine Idee, wie man dies umsetzen kann?

gruß!
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

techma hat geschrieben:Mit readlines() kann man nur die bytes angeben, die gelesen werden sollen; ich benötige einen Befehl mit dem ich angeben kann von wo bis wo die Datei ausgelesen werden soll.
Wenn alle Zeilen die gleiche Zeilenlänge haben, dann kannst du die Position mit einer einfachen Multiplikation (Zeile * Zeilenlänge) ausrechnen und mit seek() positionieren. Lesen würdest du dann mit read(), statt mit readlines().

Wenn unterschiedliche Zeilenlängen vorliegen kann niemand wissen, wo in der Datei eine neue Zeile anfängt. In dem Fall liest man dann nicht alle Zeilen mit readlines() in den Hauptspeicher, sondern arbeitet sich mit readline() zeilenweise durch.

Hier ein ungetestetes Beispiel:

Code: Alles auswählen

line_start = 18
line_end = 302424
lines = []
with open('filename', 'r') as fp:
    for line_number, line in enumerate(fp):
        if line_start < line_number < line_end:
            lines.append(line)
Irgendwo gehört da ein <= statt eines < hin.
BlackJack

@techma: Du könntest `enumerate()` verwenden, um einen Zeilenzähler zu bekommen und anhand dessen dann das einlesen beziehungsweise verarbeiten der Zeilen in einer Schleife steuern.

`itertools.islice()` wäre eine weitere Möglichkeit.

Wobei es vielleicht robuster wäre sich nicht an „magischen“ Zeilennummern, sondern am Inhalt zu orientieren. Und eventuell kann man das Problem auch lösen ohne so viele Zeilen auf einmal in den Speicher zu laden und den Inhalt „lazy“ verarbeiten.
degon
User
Beiträge: 28
Registriert: Montag 14. Juni 2010, 12:03

wenn es nur um einzelne spalten geht. genfromtxt aus dem numpy package sollte hilfreich sein.
techma
User
Beiträge: 8
Registriert: Montag 9. Januar 2012, 07:56

vielen dank für die schnellen antworten.
die methode von /me hat ganz gut funktioniert.
jedoch wurde die Ausgangsdatei nun verkleinert, sodass ich sie nun doch komplett einlesen kann
:oops:
Antworten