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]