NumPy ist eine äußerst nützliche Bibliothek, und aus ihrer Verwendung habe ich herausgefunden, dass sie in der Lage ist, Matrizen zu verarbeiten, die ziemlich groß sind (10000 x 10000). Sie beginnt jedoch mit etwas viel Größerem (versucht, eine Matrix zu erstellen) von 50000 x 50000 schlägt fehl). Dies liegt natürlich an den massiven Speicheranforderungen.
Gibt es eine Möglichkeit, in NumPy nativ große Matrizen (z. B. 1 Million mal 1 Million) nativ zu erstellen (ohne mehrere Terabyte RAM zu haben)?
PyTables und NumPy sind der Weg zu gehen.
PyTables speichert die Daten im HDF-Format mit optionaler Komprimierung auf Festplatte. Meine Datensätze erhalten häufig eine 10-fache Komprimierung, was praktisch ist, wenn es um Dutzende oder Hunderte Millionen Zeilen geht. Es ist auch sehr schnell. Mein 5 Jahre alter Laptop kann Daten mit SQL-ähnlicher GROUP BY-Aggregation mit 1.000.000 Zeilen/Sekunde durchspielen. Nicht schlecht für eine Python-basierte Lösung!
Der Zugriff auf die Daten als NumPy Recarray ist so einfach wie folgt:
data = table[row_from:row_to]
Die HDF-Bibliothek sorgt für das Einlesen der relevanten Datenblöcke und die Konvertierung in NumPy.
numpy.array
s sollen im Speicher leben. Wenn Sie mit Matrizen arbeiten möchten, die größer als Ihr RAM sind, müssen Sie dies umgehen. Es gibt mindestens zwei Ansätze, denen Sie folgen können:
scipy.sparse.csc_matrix
.Sie sollten in der Lage sein, numpy.memmap zu verwenden, um eine Datei auf der Festplatte zuzuordnen. Mit neuerer Python- und 64-Bit-Maschine sollten Sie über den erforderlichen Adressraum verfügen, ohne alles in den Speicher zu laden. Das Betriebssystem sollte nur einen Teil der Datei im Speicher behalten.
Um mit dünn besetzten Matrizen umgehen zu können, benötigen Sie das scipy
-Paket, das sich auf numpy
befindet - siehe hier . Hier finden Sie weitere Informationen zu den Optionen mit spärlicher Matrix, die Ihnen scipy
zur Verfügung stellt.
Stefano Borinis post hat mich veranlasst zu prüfen, wie weit so etwas schon ist.
Das ist es. Es scheint im Grunde zu tun, was Sie wollen. Mit HDF5 können Sie sehr große Datensätze speichern und dann auf dieselbe Weise wie NumPy darauf zugreifen und sie verwenden.
Stellen Sie sicher, dass Sie ein 64-Bit-Betriebssystem und eine 64-Bit-Version von Python/NumPy verwenden. Beachten Sie, dass Sie bei 32-Bit-Architekturen normalerweise 3 GB Arbeitsspeicher ansprechen können (wobei etwa 1 GB an Speicher zugeordneter E/A und dergleichen verloren gehen).
Mit 64-Bit-Arrays, die größer sind als die verfügbaren RAM, können Sie mit virtuellem Speicher auskommen, obwohl die Dinge langsamer werden, wenn Sie austauschen müssen. Speicherzuordnungen (siehe numpy.memmap) sind auch eine Möglichkeit, mit großen Dateien auf der Festplatte zu arbeiten, ohne sie in den Arbeitsspeicher zu laden. Sie benötigen jedoch einen 64-Bit-Adressraum, um damit arbeiten zu können. PyTables wird das meiste auch für Sie tun.
Es ist ein bisschen Alpha, aber http://blaze.pydata.org/ scheint daran zu arbeiten.
Fragen Sie, wie Sie mit einer Matrix mit 2.500.000.000 Elementen ohne Terabyte RAM umgehen können?
Um 2 Milliarden Elemente ohne 8 Milliarden Byte RAM zu verarbeiten, müssen Sie die Matrix nicht im Speicher belassen.
Das bedeutet viel ausgefeiltere Algorithmen, um es stückweise aus dem Dateisystem zu holen.
Manchmal verwendet eine einfache Lösung einen benutzerdefinierten Typ für Ihre Matrixelemente. Basierend auf dem Zahlenbereich, den Sie benötigen, können Sie eine manuelle dtype
und speziell kleinere für Ihre Artikel verwenden. Da Numpy standardmäßig den größten Typ für object berücksichtigt, kann dies in vielen Fällen hilfreich sein. Hier ist ein Beispiel:
In [70]: a = np.arange(5)
In [71]: a[0].dtype
Out[71]: dtype('int64')
In [72]: a.nbytes
Out[72]: 40
In [73]: a = np.arange(0, 2, 0.5)
In [74]: a[0].dtype
Out[74]: dtype('float64')
In [75]: a.nbytes
Out[75]: 32
Und mit benutzerdefinierten typ:
In [80]: a = np.arange(5, dtype=np.int8)
In [81]: a.nbytes
Out[81]: 5
In [76]: a = np.arange(0, 2, 0.5, dtype=np.float16)
In [78]: a.nbytes
Out[78]: 8
Soweit ich über numpy weiß, nein, aber ich könnte mich irren.
Ich kann Ihnen diese alternative Lösung vorschlagen: Schreiben Sie die Matrix auf die Festplatte und greifen Sie in Stücken darauf zu. Ich empfehle Ihnen das HDF5-Dateiformat. Wenn Sie es transparent benötigen, können Sie die ndarray-Schnittstelle erneut implementieren, um Ihre im Datenträger gespeicherte Matrix in den Arbeitsspeicher zu paginieren. Seien Sie vorsichtig, wenn Sie die Daten ändern, um sie wieder auf der Festplatte zu synchronisieren.
Wenn wir mit großen Matrizen arbeiten, implementieren wir sie normalerweise als Sparse Matrices .
Ich weiß nicht, ob Numpy spärliche Matrizen unterstützt, aber ich habe stattdessen this gefunden.
Sie können Ihren Code mit Google Colab
.Google Colab
ausführen. Dies ist ein kostenloser Cloud-Dienst. Jetzt unterstützt er kostenlose GPU! Ich könnte eine (870199 * 14425) -Matrix auf Google Colab
erstellen, die ich auf meinem PC nicht ausführen konnte.