Saltar al contenido

Trabajando con recarray

En el artículo de hoy vamos a ver el uso de numpy.recarray (o arrays estructurados) y las posibilidades que tiene usar record arrays, que no son más que arrays numpy a los que se puede acceder usando atributos y donde podemos usar diferente tipo de dato (int, float, string,…) en cada uno de los campos como si fuera una tabla de una hoja de cálculo.

[En esta entrada se ha usado numpy 1.18 sobre python 3.8 pero debería funcionar sin problemas con versiones de numpy como la 1.6 y de Python como la 2.7].

Primero de todo importamos lo necesario:

import numpy as np

Creamos una serie de vectores que serán los que usaremos a posteriori para ‘poblar’ nuestro recarray.

persona = [
    'juanlu', 'dapid',
    'kiko', 'eugenia',
    'fernando', 'maria',
    'lorena', 'angel',
   'tomas', 'susana'
]
sexo = ['v', 'v', 'v', 'm', 'v', ## 'v' para varon y 'm' para mujer
        'm', 'm', 'v', 'v', 'm']
altura = [185, 170, 175, 168, 183, 159, 152, 191, 179, 178]

Ahora, imaginad que queremos esos tres vectores de datos en un array y queremos conservar el tipo de dato de cada vector (string para persona, string para sexo y entero para la altura en centímetros) y queremos ‘titular’ cada uno de esos vectores en nuestro nuevo array y queremos acceder a cada uno de esos vectores mediante un atributo. Esto lo podremos hacer de varias maneras creando un recarray:

## Una primera forma
lista = list(zip(persona, sexo, altura))
mirecarray1 = np.array(
    lista,
    dtype = [
        ('persona', str, 10),
        ('sexo', np.str_, 1),
        ('altura', np.int)
    ]
)
mirecarray1 = mirecarray1.view(np.recarray)
## Una segunda forma
mirecarray2 = np.recarray(
    (len(persona),),
    dtype = [
        ('persona', str, 10), 
        ('sexo', np.str_, 1), 
        ('altura', np.int)
    ]
)
mirecarray2.persona = persona
mirecarray2.sexo = sexo
mirecarray2.altura = altura
## Una tercera forma
mirecarray3 = np.core.records.fromarrays(
    [persona, sexo, altura],
    names = 'persona, sexo, altura'
)
## Otras formas
## http://docs.scipy.org/doc/numpy/reference/routines.array-creation.html#creating-record-arrays-numpy-rec

Por último, veamos como podemos hacer operaciones con un recarray. Vamos a extraer la altura media de las mujeres, la altura media de los hombres, y los extremos (máximo y mínimo) de las alturas de las mujeres y de los hombres:

## Altura promedio de las mujeres
print(
    'altura promedio de las mujeres:', 
    mirecarray1.altura[mirecarray1.sexo == 'm'].mean(), 
    'cm'
)
## Altura promedio de los hombres
print(
    'altura promedio de los hombres:', 
    mirecarray1.altura[mirecarray1.sexo == 'v'].mean(), 
    'cm'
)
## Altura maxima y minima de una mujer
print(
    'altura máxima de una mujer:', 
    mirecarray1.altura[mirecarray1.sexo == 'm'].max(), 
    'cm'
)
print(
    'altura mínima de una mujer:', 
    mirecarray1.altura[mirecarray1.sexo == 'm'].min(), 
    'cm'
)
## Altura maxima y minima de un hombre
print(
    'altura máxima de un hombre:', 
    mirecarray1.altura[mirecarray1.sexo == 'v'].max(), 
    'cm'
)
print(
    'altura mínima de un hombre:', 
    mirecarray1.altura[mirecarray1.sexo == 'v'].min(), 
    'cm'
)

La salida del anterior código mostrará:

altura promedio de las mujeres: 164.25 cm
altura promedio de los hombres: 180.5 cm
altura máxima de una mujer: 178 cm
altura mínima de una mujer: 152 cm
altura máxima de un hombre: 191 cm
altura mínima de un hombre: 170 cm

Y esto ha sido todo por hoy pero no desconectéis puesto que tenemos muchas novedades en cola (y poco tiempo).

Saludos.

4 comentarios en «Trabajando con recarray»

  1. En la primera forma de crear el recarray que no es necesario usar una “list comprehension” en este caso.
    En lugar de:
    lista = [(i,j,k) for i,j,k in zip(persona, sexo, altura)]
    se puede poner directamente:
    lista = zip(persona, sexo, altura)
    Aunque, si se necesitara realizar operaciones sobre los datos antes de meterlos en el recarray, la “list comprehension” sí puede ser muy útil.
    Por otro lado, si se tuviera directamente una tupla o lista compuesta por las tres listas a introducir (por ejemplo algo como l = (persona, sexo, altura) o l = [persona, sexo, altura]), se podría desempaquetar para introducirla como argumentos separados de “zip” así:
    lista = zip(*l)
    Un saludo.

    1. Muchas gracias por los consejos. Si es que soy muy bruto a veces.
      He actualizado el código de la entrada para corregir esa ‘list comprehension’.
      Saludos.

  2. Es la primera vez que he manejado arrays estructurados (o record arrays), pero ya había oído hablar de ellos a propósito de pandas
    http://pandas.pydata.org/
    No es algo que yo haya tenido que usar mucho pero por lo visto en estadística y análisis de datos este tipo de estructuras son fundamentales.

    1. A mi me resultan útiles, cuando lees un fichero o extraes info de una BBDD y tienes un array con 57 columnas y 4 millones de registros que ya no sabes ni lo que es cada columna,… Me permite hacer operaciones de forma un poco más natural con los datos que usando el ‘broadcasting’ de numpy a pelo. Además, queda un código más legible. No digo de usarlo en todo momento, pero en ciertas situaciones son de gran ayuda.

Deja una respuesta

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

forty nine − forty one =

Pybonacci