Aggiunta di grandi quantità di dati in un database le tabelle (HDF5) dove database.numcols! = Newdata.numcols?
Domanda
Sto cercando di aggiungere un grande insieme di dati (> 30Gb) a una tabella pytables esistente. Il tavolo è N colonne, e il set di dati è N-1 colonne; una colonna viene calcolata dopo So che le altre colonne N-1.
sto usando numpy.fromfile()
a leggere pezzi del set di dati nella memoria prima di aggiungere al database. Idealmente, mi piacerebbe attaccare i dati nel database, quindi calcolare la colonna finale, e finire utilizzando Table.modifyColumn()
per completare l'operazione.
Ho considerato aggiungendo numpy.zeros((len(new_data), N))
al tavolo, quindi utilizzando Table.modifyColumns()
per riempire i nuovi dati, ma sono fiducioso che qualcuno sa un bel modo per evitare di generare una vasta gamma di dati vuoti per ogni pezzo che ho bisogno di accodamento .
Soluzione
Se le colonne sono tutti dello stesso tipo, è possibile utilizzare numpy.lib.stride_tricks.as_strided
per rendere l'array di leggere dal file di forma (L, N-1) a guardare come forma (L, N). Ad esempio,
In [5]: a = numpy.arange(12).reshape(4,3)
In [6]: a
Out[6]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
In [7]: a.strides
Out[7]: (24, 8)
In [8]: b = numpy.lib.stride_tricks.as_strided(a, shape=(4, 4), strides=(24, 8))
In [9]: b
Out[9]:
array([[ 0, 1, 2, 3],
[ 3, 4, 5, 6],
[ 6, 7, 8, 9],
[ 9, 10, 11, 112]])
Ora è possibile utilizzare questa matrice b
per riempire il tavolo. L'ultima colonna di ogni riga sarà la stessa della prima colonna della riga successiva, ma ti sovrascriverli quando è possibile calcolare i valori.
Questo non funziona se a
è record di matrice (cioè ha una dtype complesso). Per questo, si può provare numpy.lib.recfunctions.append_fields
. Come sarà copiare i dati in un nuovo array, non sarà di risparmiare una quantità significativa di memoria, ma vi permetterà di fare tutta la scrittura in una volta.
Altri suggerimenti
Si potrebbe aggiungere i risultati a un altro tavolo. A meno che non ci sia un motivo valido per la colonna calcolata per essere adiacente alle altre colonne, che è probabilmente il più facile. C'è qualcosa da dire per separare i dati grezzi dai calcoli in ogni modo.
Se è necessario aumentare la dimensione della tabella, considerare di usare h5py . Esso fornisce un'interfaccia più diretto al file h5. Tenete a mente che a seconda di come il set di dati è stato creato nel file h5, potrebbe non essere possibile semplicemente aggiungere una colonna per i dati. Vedere la sezione 1.2.4, "dataspace" in http://www.hdfgroup.org /HDF5/doc/UG/03_DataModel.html per una discussione per quanto riguarda il formato generale dei dati. supporti h5py ridimensionamento se i supporti del set di dati ad esso sottesa.
Si potrebbe anche usare un singolo buffer per memorizzare i dati di input in questo modo:
z = zeros((nrows, N))
while more_data_in_file:
# Read a data block
z[:,:N-1] = fromfile('your_params')
# Set the final column
z[:,N-1:N] = f(z[:,:N-1])
# Append the data
tables_handle.append(z)