2011-09-30 3 views
14

Ho un file HDF5 piuttosto grande generato da PyTables che sto tentando di leggere su un cluster. Sto incontrando un problema con NumPy mentre leggo in un singolo blocco. Andiamo con l'esempio:Errore in virgola mobile con Numpy e PyTables

La forma totale dell'array all'interno del file HDF5 è,

In [13]: data.shape 
Out[13]: (21933063, 800, 3) 

Ogni voce in questo array è una np.float64.

Sto riscontrando che ogni nodo ha letto sezioni di dimensioni (21933063,10,3). Sfortunatamente, NumPy sembra non essere in grado di leggere tutti i 21 milioni di sottosezioni contemporaneamente. Ho cercato di farlo sequenzialmente dividendo queste fette in 10 fette di dimensioni (2193306,10,3) e quindi utilizzando la seguente ridurre al far funzionare le cose:

In [8]: a = reduce(lambda x,y : np.append(x,y,axis=0), [np.array(data[i*  \ 
     chunksize: (i+1)*chunksize,:10],dtype=np.float64) for i in xrange(k)]) 
In [9]: 

dove 1 <= k <= 10 e chunksize = 2193306. Questo codice funziona per k <= 9; altrimenti ottengo il seguente:

In [8]: a = reduce(lambda x,y : np.append(x,y,axis=0), [np.array(data[i*  \ 
     chunksize: (i+1)*chunksize,:10],dtype=np.float64) for i in xrange(k)]) 
Floating point exception 
[email protected] 00:00:00 ~ 
$ 

Ho provato ad utilizzare lo strumento di Valgrind memcheck di capire cosa sta succedendo e sembra come se PyTables è il colpevole. I due file principali visualizzati nella traccia sono libhdf5.so.6 e un file correlato a blosc.

Si noti inoltre che se ho k=8, ottengo:

In [12]: a.shape 
Out[12]: (17546448, 10, 3) 

Ma se aggiungo l'ultima subslice, ottengo:

In [14]: a = np.append(a,np.array(data[8*chunksize:9*chunksize,:10], \ 
     dtype=np.float64)) 
In [15]: a.shape 
Out[15]: (592192620,) 

Qualcuno ha qualche idea su cosa fare ? Grazie!

+0

Qual è l'errore che si ottiene quando si leggono direttamente i dati in un array numpy? Ti suggerisco di preallocare l'array di destinazione invece di provare a crearlo aggiungendo più array. – DaveP

risposta

1

Hai provato ad allocare un array così grande prima (come suggerisce DaveP)?

In [16]: N.empty((21000000,800,3)) 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
... 
ValueError: array is too big. 

Questo è su Python a 32 bit. Avresti davvero bisogno di 20e6 * 800 * 3 * 8/1e9 = 384 GB di memoria! Un Float64 ha bisogno di 8 byte. Hai davvero bisogno dell'intero array in una sola volta?

Siamo spiacenti, non ha letto correttamente il post.

L'array con k = 8 sottoschi è già circa 4,1 GB di larghezza. Forse questo è il problema?

funziona se si utilizza solo invece di per l'ultima dimensione?

Un altro suggerimento, vorrei provare prima di ridimensionare la matrice, poi riempirla:

a = zeros((4,8,3)) 
a = resize(a, (8,8,3)) 
a[4:] = ones((4,8,3))