[GO] Sortieren Sie große Textdateien in Python

[Sortierung zusammenführen]: https://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%BC%E3%82%B8%E3%82%BD%E3%83%BC%E3% 83% 88 [io.IOBase.readlines]:http://docs.python.jp/3/library/io.html#io.IOBase.readlines

Hintergrund

Textdateien müssen in Python-Skripten sortiert werden, die in einer Windows-Umgebung ausgeführt werden.

Die Anforderungen sind wie folgt.

Die Windows-Eingabeaufforderung verfügt über einen [Sortierbefehl] [Windows-Sortierung], der das Sortieren großer Dateien unterstützt. Im Gegensatz zu [Linux sort command] und linux-sort können Sie jedoch kein Trennzeichen (-t) oder keine Sortierung als Zahl (-n) angeben.

Wenn die Größe klein ist, können Sie alle Daten mit einem Python-Skript in den Speicher laden und die Funktion [sortiert] aufrufen. Wenn die Größe jedoch groß ist, geht Ihnen möglicherweise der Speicher aus.

Ich konnte nicht anders, also entschied ich mich, die Sortierverarbeitung für große Dateien in Python zu implementieren.

Verarbeitungsverfahren

Verwenden Sie das folgende Konzept von [Sortierung zusammenführen] wie folgt, um eine große Datenmenge zu sortieren.

  1. Teilen
  2. Lesen Sie genügend Zeilen aus der Eingabedatei, um in den Speicher zu passen
  3. Sortieren Sie den gelesenen Teil und schreiben Sie ihn in eine temporäre Datei
  4. Wiederholen Sie diesen Vorgang, bis alle Eingabedateien gelesen wurden
  5. Zusammenführen
  6. Lesen Sie eine Zeile aus jeder temporären Datei
  7. Schreiben Sie den kleinsten Wert in die Ausgabedatei
  8. Wiederholen Sie diesen Vorgang, bis alle temporären Dateien gelesen wurden

Ich habe eine Folie [Verarbeitungsverfahren] erstellt, damit Sie sehen können, wie es funktioniert. マージソート_-_Qiita.png

Implementierungsmethode

Teilt

Verwenden Sie [io.IOBase.readlines], um die Datei zu teilen und zu lesen.

Wenn Sie Readlines ohne Argumente verwenden, werden alle Zeilen in den Speicher geladen. Die Verwendung von Readlines für große Dateien wird daher als Anti-Pattern bezeichnet.

Readlines können jedoch die Anzahl der Bytes / Zeichen begrenzen, die vom Argument gelesen werden sollen, sodass selbst eine große Textdatei separat gelesen werden kann.

>>> from io import StringIO
>>> f = StringIO("11\n22\n3\n4\n5\n666666\n")
>>> f.readlines(5)
['11\n', '22\n']
>>> f.readlines(5)
['3\n', '4\n', '5\n']
>>> f.readlines(5)
['666666\n']
>>> f.readlines(5)
[]

Es scheint die Anzahl der Bytes für Dateien zu sein, die im Binärmodus geöffnet wurden, und die Anzahl der Zeichen für den Textmodus.

verschmelzen

Verwenden Sie heapq.merge zum Zusammenführen. heapq.merge gibt das Ergebnis der Zusammenführung mehrerer sortierter Iterables zurück.

>>> import heapq
>>> list(heapq.merge([1, 3, 4, 7], [2, 5], [6]))
[1, 2, 3, 4, 5, 6, 7]

Quelle

Es ist in gist aufgeführt. Die Python-Version ist 3.6.

Das Folgende ist ein Auszug aus dem Sortierteil.

import heapq
import os
from contextlib import contextmanager
from operator import itemgetter
from tempfile import TemporaryDirectory, mktemp
from typing import IO, Callable, List


def large_sort(input_file: IO, output_file: IO, key: Callable=None, reverse: bool=False, limit_chars: int=1024*1024*64):

    with TemporaryDirectory() as tmp_dir:

        for lines in _read_parts(input_file, limit_chars):
            lines = sorted(lines, key=key, reverse=reverse)
            _write_part(lines, tmp_dir)

        with _open_tmp_files(tmp_dir) as tmp_files:
            for row in heapq.merge(*tmp_files, key=key, reverse=reverse):
                output_file.write(row)


def _read_parts(input_file, limit_chars):
    lines = input_file.readlines(limit_chars)
    while lines:
        yield lines
        lines = input_file.readlines(limit_chars)


def _write_part(lines, tmp_dir):
    tmp_filename = mktemp(dir=tmp_dir)
    with open(tmp_filename, "w") as tmp_file:
        tmp_file.writelines(lines)
    return tmp_filename


@contextmanager
def _open_tmp_files(tmp_dir):
    filenames = os.listdir(tmp_dir)
    files = [open(os.path.join(tmp_dir, filename), "r") for filename in filenames]
    try:
        yield files
    finally:
        for file in files:
            file.close()

In dieser Anforderung wollte ich, dass eine Funktion von einem anderen Python-Skript aufgerufen wird, daher brauche ich sie nicht, aber in der Hauptquelle habe ich sie über die Befehlszeile verfügbar gemacht, indem ich auf den sort-Befehl von Linux verwiesen habe.

Andere Ideen

Ich habe es dieses Mal selbst gemacht, aber ich werde es schreiben, weil es andere Lösungen gibt.

Recommended Posts

Sortieren Sie große Textdateien in Python
Sortieren Sie große Textdateien
Clustertext in Python
Blasensortierung in Python
Textverarbeitung mit Python
Benutzerdefinierte Sortierung in Python3
UTF8-Textverarbeitung mit Python
Sortieren Sie den Pfad natürlich in Python
Sortieren Sie große Dateien mit Python
Sprechen mit Python [Text zu Sprache]
Sortieren nach Datum in Python
Verschieben von CSV-Dateien mit Python Teil 1
GOTO in Python mit erhabenem Text 3
Bearbeiten Sie Dateien und Ordner in Python
Umgang mit JSON-Dateien in Python
Laden Sie Google Drive-Dateien in Python herunter
Extrahieren Sie mit Python Text aus Bildern
Python #sort
Lesen Sie Dateien parallel zu Python
Exportieren und Ausgeben von Dateien in Python
Das Gesetz der Zahlen in Python
Lesen und Schreiben von Text in Python
Extrahieren Sie mit Python Zeichenfolgen aus Dateien
Wenn Sie mehrere Schlüssel in Python-Sortierung angeben
Was ist neu in Python 3.9 (2) -Sortierte nicht verteilte Diagramme in Python
Suchen Sie nach Dateien wie Linux Find in Python
Ausgabebaumstruktur von Dateien in Python
Geben Sie Anmerkungen für Python2 in Stub-Dateien ein!
Automatisieren Sie Jobs, indem Sie Dateien in Python bearbeiten
Lesen und schreiben Sie JSON-Dateien mit Python
Beispiel für den Umgang mit EML-Dateien in Python
Stuge Sort in Python 3 implementiert (Bubble Sort & Quick Sort)
Versuchen Sie, Ihr Tagebuch mit Python zu durchsuchen
Laden Sie Dateien in jedem Format mit Python herunter
Lesen von Zeichen in Bildern mit Python OCR
Quadtree in Python --2
Python in der Optimierung
CURL in Python
Geokodierung in Python
SendKeys in Python
Metaanalyse in Python
Unittest in Python
Epoche in Python
Zwietracht in Python
Deutsch in Python
DCI in Python
Quicksort in Python
nCr in Python
N-Gramm in Python
Programmieren mit Python
Plink in Python
Konstante in Python
FizzBuzz in Python
SQLite in Python
Schritt AIC in Python
LINE-Bot [0] in Python
CSV in Python
Reverse Assembler mit Python
Reflexion in Python