webentwicklung-frage-antwort-db.com.de

Sehr große Matrizen mit Python und NumPy

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)?

78
Peter

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.

87
Stephen Simmons

numpy.arrays 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:

  1. Versuchen Sie eine effizientere Matrixdarstellung, die jede spezielle Struktur Ihrer Matrizen ausnutzt. Wie andere bereits erwähnt haben, gibt es beispielsweise effiziente Datenstrukturen für spärliche Matrizen (Matrizen mit vielen Nullen) wie scipy.sparse.csc_matrix .
  2. Ändern Sie Ihren Algorithmus so, dass er mit Submatrizen arbeitet. Sie können nur die Matrixblöcke von der Festplatte lesen, die derzeit in Berechnungen verwendet werden. Algorithmen, die für Cluster ausgelegt sind, arbeiten normalerweise blockweise, da die Daten auf verschiedenen Computern verteilt und nur bei Bedarf weitergegeben werden. Zum Beispiel der Fox-Algorithmus für Matrixmultiplikation (PDF-Datei) .
53

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.

30
DopplerShift

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.

24
Alex Martelli

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.

5
dwf

Es ist ein bisschen Alpha, aber http://blaze.pydata.org/ scheint daran zu arbeiten. 

5
wisty

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.

4
S.Lott

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
3
Kasrâmvd

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. 

1
Stefano Borini

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.

1

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.

0
hamed baziyad