Frage Sehr große Matrizen mit Python und NumPy


NumPy ist eine äußerst nützliche Bibliothek, und von der Verwendung habe ich festgestellt, dass sie in der Lage ist, Matrizen zu handhaben, die ziemlich groß sind (10000 x 10000), aber mit etwas viel größerem zu kämpfen beginnt (der Versuch, eine Matrix von 50000 x 50000 zu erzeugen, scheitert) ). Offensichtlich ist dies wegen der massiven Speicheranforderungen.

Gibt es eine Möglichkeit, riesige Matrizen nativ in NumPy (sagen wir 1 Million mal 1 Million) zu erstellen (ohne mehrere Terabyte RAM zu haben)?


75
2018-06-28 00:32


Ursprung


Antworten:


PyTables und NumPy sind der Weg zu gehen.

PyTables speichert die Daten auf Festplatte im HDF-Format mit optionaler Komprimierung. Meine Datensätze erhalten oft 10x Komprimierung, was praktisch ist, wenn Sie mit Dutzenden oder Hunderten von Millionen Zeilen arbeiten. Es ist auch sehr schnell; mein 5 Jahre alter Laptop kann durch Daten knacken, die SQL-like GROUP BY Aggregation bei 1.000.000 Zeilen / Sekunde machen. Nicht schlecht für eine Python-basierte Lösung!

Der Zugriff auf die Daten als NumPy-Nachschlagewerk ist wieder so einfach wie:

data = table[row_from:row_to]

Die HDF-Bibliothek sorgt dafür, dass die relevanten Datenblöcke eingelesen und in NumPy konvertiert werden.


84
2018-06-30 09:11



numpy.arrays sollen in Erinnerung bleiben. Wenn Sie mit Matrizen arbeiten möchten, die größer als Ihr RAM sind, müssen Sie das umgehen. Es gibt mindestens zwei Ansätze, denen Sie folgen können:

  1. Versuchen Sie eine effizientere Matrixdarstellung das nutzt jede spezielle Struktur, die deine Matrizen haben. Zum Beispiel, wie andere bereits gezeigt haben, gibt es effiziente Datenstrukturen für dünn besetzte Matrizen (Matrizen mit vielen Nullen), wie z scipy.sparse.csc_matrix.
  2. Ändern Sie Ihren Algorithmus, um an Submatrizen zu arbeiten. Sie können nur die Matrixblöcke von der Festplatte lesen, die gerade in Berechnungen verwendet werden. Algorithmen, die auf Clustern ausgeführt werden, arbeiten normalerweise blockweise, da die Daten über verschiedene Computer verteilt und nur bei Bedarf weitergegeben werden. Beispielsweise, der Fox-Algorithmus zur Matrixmultiplikation (PDF-Datei).

53
2018-06-28 02:53



Sie sollten numpy.memmap verwenden können, um eine Datei auf dem Datenträger abzulegen. Mit neueren Python und 64-Bit-Computer sollten Sie den erforderlichen Adressraum haben, ohne alles in den Speicher zu laden. Das Betriebssystem sollte nur einen Teil der Datei im Speicher behalten.


29
2018-06-28 01:46



Um mit dünn besetzten Matrizen umgehen zu können, benötigen Sie die scipy Paket, das auf sitzt numpy -- sehen Hier für weitere Details über die Sparse-Matrix-Optionen scipy gibt Ihnen.


24
2018-06-28 02:23



Stefano Borinis Post habe mich gefragt, wie weit das 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 die gleiche Weise wie NumPy darauf zugreifen und sie verwenden.


11
2018-06-28 02:54



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 typischerweise 3 GB Speicher adressieren können (mit etwa 1 GB, die für speicherprogrammierte E / A und dergleichen verloren gehen).

Mit 64-Bit- und Ding-Arrays, die größer als der verfügbare RAM sind, können Sie mit virtuellem Speicher auskommen, obwohl die Dinge langsamer werden, wenn Sie tauschen müssen. Speicherzuordnungen (siehe numpy.memmap) sind auch eine Möglichkeit, mit riesigen Dateien auf der Festplatte zu arbeiten, ohne sie in den Speicher zu laden. Aber auch hier muss ein 64-Bit-Adressraum zur Verfügung stehen, damit dies von großem Nutzen ist. PyTables wird das meiste für Sie tun.


5
2017-08-19 00:27



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


5
2018-02-05 00:58



Fragen Sie, wie man mit einer Matrix aus 2.500.000.000 Elementen ohne Terabyte RAM umgehen kann?

Die Möglichkeit, 2 Milliarden Elemente ohne 8 Milliarden Byte RAM zu verarbeiten, besteht darin, die Matrix nicht im Speicher zu halten.

Das bedeutet viel ausgeklügeltere Algorithmen, um es stückweise aus dem Dateisystem zu holen.


4
2018-06-28 02:32



Manchmal verwendet eine einfache Lösung einen benutzerdefinierten Typ für Ihre Matrixelemente. Basierend auf dem Zahlenbereich, den Sie benötigen, können Sie ein Handbuch verwenden dtype und speziell kleiner für Ihre Artikel. Da Numpy standardmäßig den größten Objekttyp 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
2017-10-03 22:09



Wenn wir mit großen Matrizen arbeiten, setzen wir sie normalerweise um Spärliche Matrizen.

Ich weiß nicht, ob spärliche Matrizen numpig unterstützen, aber ich habe es gefunden Dies stattdessen.


1
2018-06-28 00:45



Soviel 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 Blöcken darauf zu. Ich schlage dir das HDF5 Dateiformat vor. Wenn Sie es transparent benötigen, können Sie die ndarray-Schnittstelle neu implementieren, um die gespeicherte Matrix in den Speicher zu paginieren. Seien Sie vorsichtig, wenn Sie die Daten ändern, um sie auf dem Datenträger zu synchronisieren.


1
2018-06-28 00:46