Saltar al contenido

Aprende (funcionalidad básica de) PyTables paso a paso (I)

HDF5

El HDF5 (hierarchical dataset format, http://www.hdfgroup.org/HDF5/) es un formato que permite almacenar eficientemente grandes volúmenes de datos. Los datos se pueden almacenar de forma jerarquizada conjuntamente con metadatos. Es un formato portable que prácticamente no tiene límite en el tamaño de los datos.

PyTables

Pytables está programado sobre el formato hdf5 con ayuda de Python y Numpy. La creación, modificación y búsquedas sobre grandes conjuntos de datos es relativamente sencilla. La utilización de memoria RAM y compresión de datos están optimizados en segundo plano por la biblioteca. El espacio de disco utilizado es mucho más pequeño y el acceso a los datos suele ser más rápido comparado con bases de datos relacionales.

La versión actual es la 3.0 y es compatible con python 2.7 y 3.1 o superiores.

Para instalarlo en un linux basado en Debian podéis hacer lo siguiente (asumo que tenéis pip y numpy instalado en vuestro virtualenv científico):

sudo apt-get install libhdf5-serial-dev
pip install numexpr cython
pip install tables

Para instalarlo en Windows podéis hacerlo usando un ejecutable ya preparado por el gran Christoph Gohlke.

Si todo está correcto podemos empezar con el tutorial. Primero importamos la biblioteca

Creación de ficheros h5

import tables as tb

Ahora vamos a definir la estructura de una tabla creando una clase que deriva de la clase IsDescription (igual os suena a algo parecido a los modelos de Django). Nuestra tabla contará con una columna de fechas y tres columnas de datos ‘float’:

class EstructuraTabla(tb.IsDescription):
    fecha = tb.Int64Col(pos = 0)
    x = tb.Float32Col(pos = 1)
    y = tb.Float32Col(pos = 2)
    z = tb.Float32Col(pos = 3)

Esta clase es un constructor de tabla. Se dan nombre predefinidos a las columnas, el tipo de datos que contendrán y su posición.

Ahora creamos un nuevo fichero h5 en modo de escritura.

# Donde pone "tabla_test.h5" y "Ejemplo pybonaccico"
# puedes poner la ruta y nombre de fichero que quieras
h5file = tb.open_file(
    "tabla_test.h5",
    mode = "w",
    title = "Ejemplo pybonaccico"
)

En este caso, en el título hemos puesto algo muy estúpido pero en ese campo se puede poner algo más serio como ‘Datos aportados por Google, fecha: 2012/01/01 14.23h, proyecto PRISM ;-P’

Creamos un “grupo” en la raiz del h5 (parecido a una carpeta en un sistema de ficheros):

grupo1 = h5file.create_group(
    "/",
    'carpeta1',
    'carpeta para un primer grupo de datos'
)

carpeta1 será el nombre del grupo dentro del fichero h5 y carpeta para un primer grupo de datos serán los metadatos descriptivos que podemos asociar al grupo carpeta1.

Y ahora, dentro del grupo que acabamos de crear, creamos una tabla (que sería como un fichero en un sistema de ficheros) con la estructura de tabla que hemos definido anteriormente (clase EstructuraTabla):

tab = h5file.create_table(
    grupo1,
    "datos_carpeta1_tabla1",
    EstructuraTabla,
    "ejemplo de tabla"
)

Aquí, datos_carpeta1_tabla1 sería como el nombre del fichero (tabla) dentro de un sistema de archivos (dentro del fichero h5), EstructuraTabla es la estructura de los datos de la tabla que acabamos de definir y ejemplo de tabla es la información que asociamos a esta tabla.

En cualquier momento podemos inspeccionar la estructura que va tomando nuestro fichero h5 haciendo un print del fichero h5.

print(h5file)

Lo anterior nos debería de mostrar algo parecido a:

tabla_test.h5 (File) 'Ejemplo pybonaccico'
Last modif.: 'Thu Mar 4 21:51:41 2020'
Object Tree:
/ (RootGroup) 'Ejemplo pybonaccico'
/carpeta1 (Group) 'carpeta para un primer grupo de datos'
/carpeta1/datos_carpeta1_tabla1 (Table(0,)) 'ejemplo de tabla'

Si queremos obtener más información podemos escribir simplemente en IPython:

h5file

que nos mostrará lo siguiente:

File(filename=tabla_test.h5, title='Ejemplo pybonaccico', mode='w', root_uep='/', filters=Filters(complevel=0, shuffle=False, fletcher32=False))
/ (RootGroup) 'Ejemplo pybonaccico'
/carpeta1 (Group) 'carpeta para un primer grupo de datos'
/carpeta1/datos_carpeta1_tabla1 (Table(0,)) 'ejemplo de tabla'
 description := {
 "fecha": Int64Col(shape=(), dflt=0, pos=0),
 "x": Float32Col(shape=(), dflt=0.0, pos=1),
 "y": Float32Col(shape=(), dflt=0.0, pos=2),
 "z": Float32Col(shape=(), dflt=0.0, pos=3)}
 byteorder := 'little'
 chunkshape := (3276,)

Finalmente, cerramos la tabla creada de la siguiente forma.

h5file.close()

Y ya es suficiente por hoy, el próximo día veremos como rellenar tablas con datos ya que, de momento, solo hemos creado una estructura básica.

Saludos.

5 comentarios en «Aprende (funcionalidad básica de) PyTables paso a paso (I)»

  1. Pingback: Aprende (funcionalidad básica de) PyTables paso a paso (II) | Pybonacci

  2. Hace tiempo que tenía en mente los archivos HDF5 debido a su importancia en ciencia pero no le había dedicado tiempo, por lo que leí aquí deberé prestarle mucha mas atención, encima tiene ese formato que me cautivó de Django y SQLAlquemy para definir la estructura…
    Gracias Kiko por el excelente artículo, a la espera de los siguientes!! Hay quienes leen el diario todos los días, yo leo Pybonacci 🙂
    Un detalle en mi Debian 7.1 tuve que poner en dos sentencias separadas “pip install numexpr cython” y luego “pip install tables” porque me daba el error “You need Cython 0.13 or greater to compile PyTables!”, no tenía previamente Cython y el pip estaba instalando la versión 0.19.1.

    1. Hola, schcriher. Me alegra que te pueda resultar útil.
      He modificado el texto para corregir el tema de la instalación que comentas. Como en mi debian ya tenía instalada una versión antigua solo lo he actualizado. La próxima vez haré las pruebas en un virtualenv ‘virgen’. Gracias por el apunte.
      La verdad es que las posibilidades de HDF5 son muchas y conviene conocer PyTables. Yo trabajo con conjuntos de datos muy grandes que, en muchos casos, no caben en memoria y hay que ingeniárselas para manejarlos.
      Desde aquí tenemos que agradecer a Francesc Alted, Iván Vilata y otros el desarrollo de PyTables durante tantos años.
      Saludos.

  3. Pingback: Aprende (funcionalidad básica de) PyTabl...

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

61 − = fifty three

Pybonacci