enregistrer le tableau numpy en mode ajout
est-il possible de sauvegarder un tableau numpy en l'ajoutant à un npy-file - - - quelque chose comme np.save(filename,arr,mode='a')?
j'ai plusieurs fonctions qui ont pour parcourir les lignes d'un grand tableau. Je ne peux pas créer le tableau à la fois à cause des contraintes de mémoire. Pour éviter de créer les lignes encore et encore, je voulais créer chaque ligne une fois et l'enregistrer pour le fichier l'ajoutant à la ligne précédente dans le fichier. Plus tard, je pourrais charger le fichier npy dans mmap_mode, en accédant aux tranches en cas de besoin.
4 réponses
Le .npy le format de fichier est parfaitement parfait pour travailler avec de petits ensembles de données, sans compter sur des modules externes autres que numpy.
cependant, lorsque vous commencez à avoir de grandes quantités de données, l'utilisation d'un format de fichier, tel que HDF5, conçu pour traiter de tels ensembles de données, est préférable [1].
Pour l'exemple, ci-dessous est une solution pour sauver numpy tableaux en HDF5 avec PyTables,
Étape 1: Créer extensible EArray stockage
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()
Étape 2: Ajouter des lignes à un ensemble de données existant (si nécessaire)
f = tables.open_file(filename, mode='a')
f.root.data.append(x)
Étape 3: relisez un sous-ensemble des données
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
pour ajouter des données à un fichier existant en utilisant numpy.enregistrer, il faut utiliser:
f_handle = file(filename, 'a')
numpy.save(f_handle, arr)
f_handle.close()
j'ai vérifié qu'il fonctionne en python 2.7 et numpy 1.10.4
j'ai adapté le code de ici, qui parle de la méthode savetxt.
.npy les fichiers contiennent l'en-tête qui a la forme et le dtype du tableau. Si vous savez à quoi ressemble votre tableau résultant, vous pouvez écrire l'en-tête vous-même puis les données en morceaux. Par exemple, voici le code des matrices 2D concaténantes:
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'))
si vous avez besoin d'une solution plus générale (éditer l'en-tête en place en ajoutant), vous devrez recourir à fseek trucs comme dans [1].
Inspiré par
[1]: https://mail.scipy.org/pipermail/numpy-discussion/2009-August/044570.html (ne pas travailler hors de la boîte)
[2]: https://docs.scipy.org/doc/numpy/neps/npy-format.html
[3]: https://github.com/numpy/numpy/blob/master/numpy/lib/format.py
vous pouvez essayer quelque chose comme lire le fichier puis ajouter de nouvelles données
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
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]