2016-04-21 19 views
1

Gibt es eine Methode, um ein numpy memmap Array in eine .npy Datei zu speichern? Offensichtlich gibt es ein Verfahren, aus einer Datei .npy solch eine Anordnung zu laden, wieFlushing numpy memmap zu npy Datei

data = numpy.load("input.npy", mmap_mode='r') 

folgt, aber die Datei Spülung ist nicht gleichwertig in einem .npy Format zu speichern.

Wenn Spülen die einzige Möglichkeit ist, zu gehen, gibt es eine Möglichkeit, die Form des gespeicherten Arrays abzuleiten? Ich hätte lieber eine dynamische Form, die automatisch in einem anderen Skript gespeichert und wieder abgerufen wird (möglicherweise als memmap).

Ich habe an verschiedenen Stellen darüber gesucht, aber kein Ergebnis gefunden. Ich Art und Weise zu speichern, in .npy ich jetzt

numpy.save(output.filename, output.copy()) 

ist, die die Idee besiegt von memmap verwenden, aber bewahrt die Form.

HINWEIS: Ich weiß über hdf5 und h5py, aber ich frage mich, ob es eine reine numpy Lösung zu diesem gibt.

Antwort

3

Gibt es eine Möglichkeit, die Form des gespeicherten Arrays abzuleiten?

No. Soweit es np.memmap betrifft, ist die Datei nur ein Puffer - sie speichert den Inhalt des Arrays, aber nicht die Dimensionen, dtype usw. Es gibt keine Möglichkeit, diese Informationen abzuleiten, wenn sie nicht irgendwie im Array selbst enthalten sind. Wenn Sie bereits eine np.memmap erstellt haben, die von einer einfachen Binärdatei unterstützt wird, müssen Sie den Inhalt in eine neue .npy Datei auf dem Datenträger schreiben.

Sie vermeiden könnte die neue .npy Datei als eine andere Memory-Mapped-Array mit numpy.lib.format.open_memmap eine Kopie im Speicher zu erzeugen durch Öffnen:

import numpy as np 
from numpy.lib.format import open_memmap 

# a 10GB memory-mapped array 
x = np.memmap('/tmp/x.mm', mode='w+', dtype=np.ubyte, shape=(int(1E10),)) 

# create a memory-mapped .npy file with the same dimensions and dtype 
y = open_memmap('/tmp/y.npy', mode='w+', dtype=x.dtype, shape=x.shape) 

# copy the array contents 
y[:] = x[:] 
+1

Diese 'open_memmap' Funktion eine große Erkenntnis ist - ich brauche nur die Möglichkeit, ein' zu beginnen .npy' gesichert Array aber das Hinzufügen eine Option ein Array zu speichern, das in einer Binärdatei stecken bleiben könnte, ist noch besser. – pevogam

1

Haftungsausschluss: Die folgenden Arbeiten mit numpy Version 1.11.2 (und später nehme ich an), aber eine frühere Version, die ich versuchte (1.8.2) gab einen Fehler.

Ein mit np.save gespeichertes Array ist im Wesentlichen eine memmap mit einer Kopfzeile, die dtype, shape und element order angibt. Sie können mehr darüber in der numpy documentation lesen. Wenn Sie Ihre np.memmap erstellen, können Sie Speicherplatz für diese Kopfzeile mit dem Parameter offset reservieren. Hinweis: Die Dokumentation gibt an, dass die Header-Länge ein Vielfaches von 16 sein sollte:

Sagen wir, Sie 5 * reservieren 16 = 80 Bytes für den Header (mehr dazu weiter unten):

import numpy as np 
x = np.memmap('/tmp/x.npy', mode='w+', dtype=np.ubyte, shape=(int(1E10),), offset=80) 

Dann, wenn Sie manipulieren die memmap fertig, können Sie den Header erstellen und schreiben, mit np.lib.format:

header = np.lib.format.header_data_from_array_1_0(x) 

with open('/tmp/x.npy', 'r+b') as f: 
    np.lib.format.write_array_header_1_0(f, header) 

Beachten Sie, dass dies den Header von Anfang an der memmap Datei schreibt, also wenn len(header) > 80, dann wird es ein Teil der Daten überschreiben und deine Datei wird n nicht lesbar sein.Der Header ist eine magische Zeichenfolge fester Länge, zwei Versionsbytes, zwei Bytes, die die Headerlänge angeben, und eine Zeichenfolgendarstellung eines Dictionary, die 'shape', 'descr' und 'order' angibt. Wenn Sie die Form und den D-Typ (descr) Ihres Arrays kennen, können Sie einfach die Header-Länge berechnen (ich habe es aus Gründen der Einfachheit oben bei 80 festgelegt).

Nach den Header schreiben, können Sie die Daten np.load mit laden:

y = np.load('/tmp/x.npy')