numpy: effizient Lesen in einem großen array
Ich habe eine binäre Datei, die enthält ein dichtes n*m
matrix von 32-bit floats. Was ist der effizienteste Weg, um es zu Lesen in einem Fortran-bestellt numpy
array?
Die Datei ist mehrere gigabyte groß ist. Ich bekomme das format, aber es muss kompakt sein (d.h. über 4*n*m
bytes in der Länge) und müssen leicht zu produzieren, die aus nicht-Python-code.
Bearbeiten: Es ist unerlässlich, dass die Methode erzeugt einen Fortran-bestellt matrix direkt (aufgrund der Größe der Daten, die ich nicht leisten können, zu erstellen Sie ein C-bestellt matrix und dann verwandeln Sie es in eine separate Fortran-bestellt kopieren.)
- Nicht scipy.org/Cookbook/InputOutput die Antwort auf Ihre Frage? (Siehe Abschnitt "Binärdateien")
- Danke. In der Tat, ich habe bereits das Experimentieren mit einigen der dort beschriebenen Methoden. Ich bin mit der Frage in der Hoffnung, dass jemand kommen würde, nach vorne, entweder hat erste-hand-Erfahrung zu tun, was ich versuche zu tun, oder ist vertraut mit
numpy
Interna und können Sie beraten, aus diesem Winkel. - Im Allgemeinen habe ich gefunden beim Lesen von sehr großen arrays in numpy, die ich brauche, um zu wissen, die Größe im Voraus, um pre-allocate der entsprechende array, um die Daten aufzunehmen. Wissen Sie, die Größe im Voraus? Wenn nicht, versuchen Sie es mit einem zwei-pass-Ansatz: erst Scannen, um entdecken Größe/Abmessungen Daten dann zuordnen array, dann Lesen/Parsen, in Arrays.
- Guter Punkt, danke. Ich weiß, die Größe im Voraus (ich kontrolliere das Daten-format, so kann ich schreiben Sie sich die Größe, die als Teil der Datei-header.)
Du musst angemeldet sein, um einen Kommentar abzugeben.
NumPy bietet
fromfile()
zum Lesen binärer Daten.erstellt ein eindimensionales array mit den Daten. Zugriff auf eine zweidimensionale Fortran-bestellt
n x m
matrix können Sie Form:[EDIT: Die
reshape()
tatsächlich kopiert die Daten in diesem Fall (siehe die Kommentare). Dies zu tun, ohne cpoying, verwenden SieDank Joe Kingtion für den Hinweis.]
Aber um ehrlich zu sein, wenn die matrix mehrere Gigabyte, würde ich für einen im HDF5-Tools wie h5py oder PyTables. Beide haben die tools, FAQ-Einträge vergleicht man das Werkzeug auf die andere. Ich in der Regel lieber h5py, obwohl PyTables scheint zu sein, häufiger verwendet (und die Bereiche der beiden Projekte sind etwas anders).
Im HDF5 Dateien geschrieben werden können, werden von den meisten Programmiersprachen verwendet bei der Analyse der Daten. Die Liste der Schnittstellen in den verlinkten Wikipedia-Artikel ist nicht vollständig, da gibt es zum Beispiel auch ein R-Schnittstelle. Aber ich weiß nicht, welche Sprache Sie verwenden möchten, um die Daten zu schreiben...
n*m
array für die Speicherung einer großen dichten matrix mit Fließkommazahlen?a = numpy.fromfile("filename", dtype=numpy.float32)
gefolgt vona = a.reshape((n, m), order="FORTRAN")
auf eine 4GB-Datei, ist dies möglicherweise ein 4GB "C" matrix im Speicher nur, um sofort machen ein anderes 4GB Kopie im Arbeitsspeicher, um es umzudrehen in die Fortran-format?numpy
matrix nicht kopieren Sie die Daten. Jedoch aus performance-Gründen mache ich die Pflege über, wie Sachen im Arbeitsspeicher gespeichert, und ich kann nicht leisten, haben zwei Kopien des gleichen multi-gigabyte-matrix um, daher meine Fragen.a = np.fromfile(...)
und danna = a.reshape((m,n)).T
. Dies wird nicht eine Kopie erstellen, und hat genau den gleichen Effekt.np.fromfile()
gibt eineC
matrix (tut es das? kann ich das ändern?) Jetztreshape
änderungen der schreitende. Ich nehme an, dass die transpose-funktioniert auch durch ändern der schreitende (oder bin ich hier falsch?) Also das Endergebnis ist immer noch einC
matrix, nicht?np.fromfile()
tut? Es gibt nichts in der Dokumentation, und keine Parameter, die ich finden konnte, die diese Steuern.np.fromfile
es Lesen in der Reihenfolge, in der es gespeichert wie auf der Festplatte. Wie ich schon sagte, ich war der Annahme, dass es bereits auf der Festplatte gespeichert, in Fortran bestellen. Wenn Sie möchten schreiben Sie ein C-bestellt-array auf dem Datenträger als Fortran bestellt array benutzen Sie einfacha.ravel('F').tofile(fid)
.Grundsätzlich Numpy speichert die arrays als flache Vektoren. Die verschiedenen Dimensionen sind nur eine illusion, geschaffen durch die verschiedenen Ansichten und Schritten, dass die Numpy-iterator verwendet.
Für eine Gründliche, aber leicht zu Folgen Erläuterungen, wie Numpy intern funktioniert, siehe die ausgezeichnete Kapitel 19 Der Schöne Code-Buch.
Mindestens Numpy
array()
undreshape()
ein argument für C ('C'), Fortran ('F') oder erhaltenen Auftrages ('A').Siehe auch die Frage Wie zu zwingen, numpy-array, um fortran-Stil?
Ein Beispiel mit der Standard-C-Indizierung (row-major-Reihenfolge):
Indizierung mit Fortran Bestellung (column-major-Reihenfolge):
Die andere Ansicht
Können, können Sie auch immer die andere Art der Ansicht über den parameter T einen array:
Sie können auch manuell die Schritte: