wake-up-neo.com

speichere numpy array im append modus

Ist es möglich, ein numpy-Array zu speichern, das an eine bereits vorhandene npy-Datei angehängt wird, etwa np.save(filename,arr,mode='a')?

Ich habe mehrere Funktionen, die über die Zeilen eines großen Arrays iterieren müssen. Ich kann das Array wegen Speicherbeschränkungen nicht sofort erstellen. Um zu vermeiden, dass die Zeilen immer wieder erstellt werden, wollte ich jede Zeile einmal erstellen und in einer Datei speichern, die sie an die vorherige Zeile in der Datei anhängt. Später konnte ich die npy-Datei in mmap_mode laden und bei Bedarf auf die Slices zugreifen.

21
user3820991

Das eingebaute .npy-Dateiformat eignet sich hervorragend für die Arbeit mit kleinen Datensätzen, ohne auf externe Module außer numpy angewiesen zu sein.

Wenn Sie jedoch mit großen Datenmengen beginnen, ist die Verwendung eines Dateiformats wie HDF5, das für die Verarbeitung solcher Datensätze vorgesehen ist, zu bevorzugen [1]

Im Folgenden finden Sie eine Lösung zum Speichern von numpy-Arrays in HDF5 mit PyTables ,

Schritt 1: Erstellen Sie eine erweiterbare EArray storage 

import tables
import numpy as np

filename = 'outarray.h5'
ROW_SIZE = 100
NUM_COLUMNS = 200

f = tables.open_file(filename, mode='w')
atom = tables.Float64Atom()

array_c = f.create_earray(f.root, 'data', atom, (0, ROW_SIZE))

for idx in range(NUM_COLUMNS):
    x = np.random.Rand(1, ROW_SIZE)
    array_c.append(x)
f.close()

Schritt 2: Anfügen von Zeilen an eine vorhandene Datenmenge (falls erforderlich)

f = tables.open_file(filename, mode='a')
f.root.data.append(x)

Schritt 3: Lesen Sie einen Teil der Daten zurück

f = tables.open_file(filename, mode='r')
print(f.root.data[1:10,2:20]) # e.g. read from disk only this part of the dataset
18
rth

Für das Anhängen von Daten an eine bereits vorhandene Datei mithilfe von numpy.save sollten wir Folgendes verwenden:

f_handle = file(filename, 'a')
numpy.save(f_handle, arr)
f_handle.close()

Ich habe überprüft, dass es in Python 2.7 und Numpy 1.10.4 funktioniert

Ich habe den Code von here angepasst, der von der savetxt-Methode spricht.

4
Mohit Pandey

.npy-Dateien enthalten einen Header, der die Form und den Typ des Arrays enthält. Wenn Sie wissen, wie Ihr resultierendes Array aussieht, können Sie selbst den Header und dann Daten in Abschnitten schreiben. Zum Beispiel ist hier der Code zum Verketten von 2d-Matrizen:

import numpy as np
import numpy.lib.format as fmt

def get_header(fnames):
    dtype = None
    shape_0 = 0
    shape_1 = None
    for i, fname in enumerate(fnames):
        m = np.load(fname, mmap_mode='r') # mmap so we read only header really fast
        if i == 0:
            dtype = m.dtype
            shape_1 = m.shape[1]
        else:
            assert m.dtype == dtype
            assert m.shape[1] == shape_1
        shape_0 += m.shape[0]
    return {'descr': fmt.dtype_to_descr(dtype), 'fortran_order': False, 'shape': (shape_0, shape_1)}

def concatenate(res_fname, input_fnames):
    header = get_header(input_fnames)
    with open(res_fname, 'wb') as f:
        fmt.write_array_header_2_0(f, header)
        for fname in input_fnames:
            m = np.load(fname)
            f.write(m.tostring('C'))

Wenn Sie eine allgemeinere Lösung benötigen (Kopfzeile beim Anhängen bearbeiten), müssen Sie auf fseek-Tricks wie in [1] zurückgreifen.

Inspiriert von
[1]: https://mail.scipy.org/pipermail/numpy-discussion/2009-August/044570.html (funktioniert nicht sofort)
[2]: https://docs.scipy.org/doc/numpy/neps/npy-format.html
[3]: https://github.com/numpy/numpy/blob/master/numpy/lib/format.py

1
Evgeny Remizov

Dies ist eine Erweiterung der Antwort von Mohit Pandey, die ein Beispiel zum vollständigen Speichern/Laden zeigt. Es wurde mit Python 3.6 und Numpy 1.11.3 getestet.

from pathlib import Path
import numpy as np
import os

p = Path('temp.npy')
with p.open('ab') as f:
    np.save(f, np.zeros(2))
    np.save(f, np.ones(2))

with p.open('rb') as f:
    fsz = os.fstat(f.fileno()).st_size
    out = np.load(f)
    while f.tell() < fsz:
        out = np.vstack((out, np.load(f)))

out = Array ([[0., 0.], [1., 1.]])

1
PaxRomana99

sie können etwas versuchen, beispielsweise die Datei lesen und neue Daten hinzufügen 

import numpy as np
import os.path

x = np.arange(10) #[0 1 2 3 4 5 6 7 8 9]

y = np.load("save.npy") if os.path.isfile("save.npy") else [] #get data if exist
np.save("save.npy",np.append(y,x)) #save the new

nach 2 Operationen:

print(np.load("save.npy")) #[0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9]
0
Sakhri Houssem