Ich muss eine große Datei Zeile für Zeile lesen. Nehmen wir an, die Datei hat mehr als 5 GB und ich muss jede Zeile lesen, aber ich möchte sie natürlich nicht verwenden, readlines()
da dadurch eine sehr große Liste im Speicher erstellt wird.
Wie funktioniert der folgende Code für diesen Fall? Liest xreadlines
sich eins nach dem anderen ins Gedächtnis? Wird der Generatorausdruck benötigt?
f = (line for line in open("log.txt").xreadlines()) # how much is loaded in memory?
f.next()
Und was kann ich tun, um dies in umgekehrter Reihenfolge zu lesen, genau wie der Linux- tail
Befehl?
Ich fand:
http://code.google.com/p/pytailer/
und
" Python Kopf, Schwanz und rückwärts gelesen durch Zeilen einer Textdatei "
Beides hat sehr gut funktioniert!
Antworten:
Ich habe diese Antwort gegeben, weil Keith's die Datei zwar kurz, aber nicht explizit schließt
quelle
for
Schleife zu verwenden, die über die Zeilen iteriert, können Sie Blöckechunk = infile.read(chunksize)
mit begrenzter Größe unabhängig von ihrem Inhalt lesen. Sie müssen selbst in den Chunks nach Zeilenumbrüchen suchen.Sie müssen lediglich das Dateiobjekt als Iterator verwenden.
Noch besser ist die Verwendung des Kontextmanagers in neueren Python-Versionen.
Dadurch wird auch die Datei automatisch geschlossen.
quelle
Ein Ansatz der alten Schule:
quelle
Verwenden Sie stattdessen besser einen Iterator. Relevant: http://docs.python.org/library/fileinput.html
Aus den Dokumenten:
Dadurch wird vermieden, dass die gesamte Datei auf einmal in den Speicher kopiert wird.
quelle
close()
Methode des zurückgegebenenFileInput
Klassenobjekts nicht auf, wenn die Schleife beendet ist. Daher würde ich es auf diese Weise vermeiden. In Python 3.2 haben sie es endlichfileinput
mit dem Kontextmanager-Protokoll kompatibel gemacht , das dieses Problem behebt (aber der Code würde immer noch nicht so geschrieben, wie gezeigt).Folgendes tun Sie, wenn die Datei keine Zeilenumbrüche enthält:
quelle
Bitte versuchen Sie dies:
quelle
Ich konnte nicht glauben, dass es so einfach sein könnte, wie es die Antwort von @ john-la-rooy schien. Also habe ich den
cp
Befehl durch zeilenweises Lesen und Schreiben neu erstellt. Es ist verrückt schnell.quelle
readline
Zeilenenden standardisiert, hat dies den Nebeneffekt, dass Dokumente mit DOS-Zeilenenden von\r\n
in Unix-Zeilenenden von konvertiert werden\n
. Mein ganzer Grund für die Suche nach diesem Thema war, dass ich eine Protokolldatei konvertieren musste, die ein Durcheinander von Zeilenenden empfängt (weil der Entwickler blind verschiedene .NET-Bibliotheken verwendet hat). Ich war schockiert, als ich feststellte, dass ich nach meinem ersten Geschwindigkeitstest nicht zurück undrstrip
die Linien gehen musste. Es war schon perfekt!Das Blaze- Projekt hat in den letzten 6 Jahren einen langen Weg zurückgelegt. Es verfügt über eine einfache API, die eine nützliche Teilmenge der Pandas-Funktionen abdeckt.
dask.dataframe kümmert sich intern um das Chunking, unterstützt viele parallelisierbare Vorgänge und ermöglicht das einfache Exportieren von Slices zurück in Pandas für In-Memory-Vorgänge.
quelle
Hier ist der Code zum Laden von Textdateien beliebiger Größe, ohne Speicherprobleme zu verursachen. Es unterstützt Dateien mit einer Größe von Gigabyte
https://gist.github.com/iyvinjose/e6c1cb2821abd5f01fd1b9065cbc759d
Laden Sie die Datei data_loading_utils.py herunter und importieren Sie sie in Ihren Code
Verwendung
Die Methode process_lines ist die Rückruffunktion. Es wird für alle Zeilen aufgerufen, wobei Parameterdaten jeweils eine einzelne Zeile der Datei darstellen.
Sie können die Variable CHUNK_SIZE abhängig von der Hardware-Konfiguration Ihrer Maschine konfigurieren.
quelle
Wie wäre es damit? Teilen Sie Ihre Datei in Blöcke und lesen Sie sie dann Zeile für Zeile, da Ihr Betriebssystem beim Lesen einer Datei die nächste Zeile zwischenspeichert. Wenn Sie die Datei Zeile für Zeile lesen, nutzen Sie die zwischengespeicherten Informationen nicht effizient.
Teilen Sie stattdessen die Datei in Blöcke und laden Sie den gesamten Block in den Speicher. Führen Sie dann Ihre Verarbeitung durch.
quelle
Danke dir! Ich habe kürzlich auf Python 3 konvertiert und war frustriert, weil ich Readlines (0) zum Lesen großer Dateien verwendet habe. Dies löste das Problem. Aber um jede Zeile zu bekommen, musste ich ein paar zusätzliche Schritte machen. Vor jeder Zeile stand ein "b", das vermutlich im Binärformat war. Mit "decode (utf-8)" wurde es ascii geändert.
Dann musste ich ein "= \ n" in der Mitte jeder Zeile entfernen.
Dann habe ich die Zeilen an der neuen Zeile geteilt.
Hier ist der Code, der direkt über "Daten drucken" in Arohis Code beginnt.
quelle
In dieser anderen Frage habe ich hier einen Parallelzugriffsansatz auf Byte-Ebene demonstriert:
Abrufen der Anzahl der Zeilen in einer Textdatei ohne Readlines
Einige der bereits gegebenen Antworten sind nett und prägnant. Ich mag einige von ihnen. Aber es hängt wirklich davon ab, was Sie mit den Daten in der Datei machen möchten. In meinem Fall wollte ich nur Zeilen zählen, so schnell wie möglich bei großen Textdateien. Mein Code kann natürlich auch geändert werden, um andere Dinge zu tun, wie jeden Code.
quelle
Die beste Lösung, die ich in dieser Hinsicht gefunden habe, und ich habe es mit einer 330-MB-Datei versucht.
Wobei line_length die Anzahl der Zeichen in einer einzelnen Zeile ist. Zum Beispiel hat "abcd" die Zeilenlänge 4.
Ich habe 2 Zeilen hinzugefügt, um das Zeichen '\ n' zu überspringen und zum nächsten Zeichen zu wechseln.
quelle
Dies kann nützlich sein, wenn Sie parallel arbeiten und nur Datenblöcke lesen möchten, diese aber mit neuen Zeilen sauber halten möchten.
quelle
hoffe das hilft.
quelle