2015-05-21 6 views
14

È possibile salvare un array numpy aggiungendolo a un file npy già esistente --- qualcosa come np.save(filename,arr,mode='a')?salva array numpy in modalità append

Ho diverse funzioni che devono scorrere sulle righe di un grande array. Non riesco a creare l'array in una volta sola a causa dei limiti di memoria. Per evitare di creare le righe più e più volte, volevo creare ogni riga una volta e salvarla nel file aggiungendola alla riga precedente del file. Successivamente ho potuto caricare il file npy in mmap_mode, accedendo alle fette quando necessario.

risposta

8

Il formato file incorporato .npy è perfettamente adatto per lavorare con dataset di piccole dimensioni, senza fare affidamento su moduli esterni diversi da numpy.

Tuttavia, quando si inizia ad avere grandi quantità di dati, l'uso di un formato di file, come HDF5, progettato per gestire tali set di dati, è da preferire [1].

Ad esempio, sotto è una soluzione per salvare numpy matrici in HDF5 con PyTables,

Passaggio 1: Creare un estensibile EArray stoccaggio

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() 

Fase 2: aggiungere righe a una esistente dataset (se necessario)

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

Fase 3: Leggere indietro un sottoinsieme dei dati

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 
+3

grazie per avermi a PyTables. Un approccio un po 'più semplice usando la classe Array era sufficiente per il mio scopo. Sono curioso del motivo per cui non esiste una modalità di aggiunta per 'np.save'. Se fosse sensato, immagino che sarebbe stato implementato. – user3820991

+0

È ancora il miglior metodo nel 2018? – Moondra

3

per l'aggiunta di dati in un file già esistente utilizzando numpy.save, dovremmo usare:

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

ho verificato che Lavori in python 2.7 e NumPy 1.10.4

ho trovato il codice here

+3

Ho appena controllato e non funziona in 'python 2.7.12' e' numpy 1.12.1'. L'array rimane lo stesso, non viene aggiunto nulla.Nota inoltre che il link che hai fornito parla del metodo 'savetxt', non' np.save'. –

+1

Sono stato in grado di utilizzare questo tipo di modello di impilamento con successo con python 3.5 e numpy 1.11.3. Sebbene fosse necessario aprire il file in modalità binaria. – PaxRomana99

0

I filecontengono un'intestazione che ha forma e dtype dell'array al suo interno. Se si conosce l'aspetto della matrice risultante, è possibile scrivere direttamente l'intestazione e quindi i dati in blocchi. Per esempio, ecco il codice per concatenare matrici 2D:

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')) 

Se avete bisogno di una soluzione più generale (Modifica intestazione in posizione mentre aggiungendo) si dovrà ricorrere a trucchi fseek come in [1].

Ispirato
[1]: https://mail.scipy.org/pipermail/numpy-discussion/2009-August/044570.html (non funziona out of the box)
[2]: https://docs.scipy.org/doc/numpy/neps/npy-format.html
[3]: https://github.com/numpy/numpy/blob/master/numpy/lib/format.py