python - Excepción de punto flotante con Numpy y PyTables
hdf5 (1)
Tengo un archivo HDF5 bastante grande generado por PyTables que estoy intentando leer en un clúster. Me estoy topando con un problema con NumPy ya que leo en una porción individual. Vayamos con el ejemplo:
La forma total de la matriz dentro del archivo HDF5 es,
In [13]: data.shape
Out[13]: (21933063, 800, 3)
Cada entrada en esta matriz es un np.float64
.
Estoy haciendo que cada nodo lea porciones de tamaño (21933063,10,3)
. Desafortunadamente, NumPy parece ser incapaz de leer todos los 21 millones de servicios a la vez. He intentado hacer esto de forma secuencial al dividir estos cortes en 10 cortes de tamaño (2193306,10,3)
y luego usar los siguientes (2193306,10,3)
para que las cosas funcionen:
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 lo 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
home@mybox 00:00:00 ~
$
Intenté usar la herramienta memcheck
de Valgrind para descubrir qué está pasando y parece que PyTables es el culpable. Los dos archivos principales que aparecen en la traza son libhdf5.so.6
y un archivo relacionado con blosc
.
Además, tenga en cuenta que si tengo k=8
, obtengo:
In [12]: a.shape
Out[12]: (17546448, 10, 3)
Pero si agrego la última subsección, obtengo:
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!
¿Intentaste 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. ¡Realmente necesitarías 20e6 * 800 * 3 * 8 / 1e9 = 384 GBytes de memoria! Un Float64 necesita 8 bytes. ¿Realmente necesitas toda la gama a la vez?
Lo siento, no leí el post correctamente.
Su matriz con k = 8 sub-servicios ya tiene aproximadamente 4.1 GByte. ¿Tal vez ese sea el problema?
¿Funciona si usa solo 8 en lugar de 10 para la última dimensión?
Otra sugerencia, primero intentaría cambiar el tamaño de la matriz y luego rellenarla:
a = zeros((4,8,3))
a = resize(a, (8,8,3))
a[4:] = ones((4,8,3))