2011-09-30 5 views
14

Tengo un archivo HDF5 bastante grande generado por PyTables que estoy intentando leer en un clúster. Tengo un problema con NumPy cuando leo en un fragmento individual. Vamos con el ejemplo:Excepción de punto flotante con Numpy y PyTables

La forma total de la matriz dentro del archivo HDF5 es,

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

Cada elemento de esta tabla es una np.float64.

Estoy teniendo cada nodo leído secciones del tamaño (21933063,10,3). Desafortunadamente, NumPy parece ser incapaz de leer los 21 millones de subslices a la vez. He tratado de hacer esto de forma secuencial mediante la fragmentación de estas rebanadas en 10 rebanadas de tamaño (2193306,10,3) y luego utilizando la siguiente reducir para hacer las cosas de trabajo:

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]: 

donde 1 <= k <= 10 y chunksize = 2193306. Este código funciona para k <= 9; de lo contrario me sale el siguiente:

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 ~ 
$ 

He intentado utilizar la herramienta de Valgrind memcheck de averiguar lo que está pasando y parece como si PyTables es el culpable. Los dos archivos principales que aparecen en el seguimiento son libhdf5.so.6 y un archivo relacionado con blosc.

Además, tenga en cuenta que si tengo k=8, me sale:

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

Pero si añado el último subslice, me sale:

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

¿Alguien tiene alguna idea de qué hacer ? ¡Gracias!

+0

¿Cuál es el error que se obtiene al leer directamente los datos en una matriz numpy? Sugeriría que preasigne su matriz de destino en lugar de intentar crearla agregando varias matrices. – DaveP

Respuesta

1

¿Intentó asignar una matriz tan grande antes (como sugiere DaveP)?

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

Esto es en 32bit Python. ¡De hecho necesitaría 20e6 * 800 * 3 * 8/1e9 = 384 GBytes de memoria! One Float64 necesita 8 bytes. ¿Realmente necesitas toda la matriz a la vez?

Lo siento, no leí la publicación correctamente.

Su matriz con k = 8 subslices ya tiene unos 4,1 GBy de tamaño. ¿Tal vez ese sea el problema?

¿Funciona si sólo utiliza 8 en lugar de 10 de la última dimensión?

Otra sugerencia, me gustaría probar primero en cambiar el tamaño de la matriz, y luego llenarlo:

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