Pybonacci

Computación Científica con Python en castellano

¿Cómo trabajar con arrays de binarios en Python?

with 5 comments

Esta semana vamos con una pregunta de Gonzalo, que nos dice por email:

Saludos. Últimamente he estado trabajado en python y me gusta mucho. En estos momentos estoy haciendo un algoritmo genético con codificación en numeros binarios utilizando bitset de C++. ¿Tendran información acerca de como trabajar con cadenas de binarios en python? Gracias y Felicidades por el blog.

He investigado un poco acerca de bitset en la referencia de C++, y leo que se trata básicamente de un array de valores booleanos, optimizados para su almacenamiento en memoria.

Esto es exactamente lo que puedes conseguir con los arrays de NumPy: son contenedores de datos homogéneos, que se almacenan eficientemente en memoria e implementados en C para que su manejo sea mucho más rápido. En nuestro blog tienes muchos artículos sobre NumPy, como por ejemplo este tutorial sobre los distintos métodos para crear arrays:

http://pybonacci.wordpress.com/2012/06/11/como-crear-matrices-en-python-con-numpy/

Para que los arrays funcionen como bitset, tienen que tener el dtype bool. Puedes conseguir esto de varias maneras:

  • Creando el array a partir de una lista de valores True y False:
>>> np.array([True, False, True])
array([ True, False,  True], dtype=bool
  • Utilizando el argumento dtype=bool para hacer una conversión explícita:
>>> np.array([1, 0, -2.5], dtype=bool)
array([ True, False,  True], dtype=bool)
  • Utilizando el método astype:
>>> np.arange(-3, 3).astype(bool)
array([ True,  True,  True, False,  True,  True], dtype=bool)
  • Utilizando las funciones lógicas de NumPy:
>>> np.arange(-3, 3) < 0
array([ True,  True,  True, False, False, False], dtype=bool)
>>> np.isinf(np.arange(-2, 2) / 0)
array([ True,  True, False,  True], dtype=bool)

(Puedes consultar un listado en http://docs.scipy.org/doc/numpy/reference/routines.logic.html)

A partir de ahí, tienes todas las funciones de NumPy y toda la potencia de Python a tu disposición.

¡Y hasta aquí la pregunta de la semana! :) Y tú, ¿has trabajado con arrays booleanos en NumPy? ¿Crees que hay algo que otros lenguajes tienen y que a Python le falta en este sentido? O al contrario, ¿te has encontrado con que con NumPy tienes ventajas que de otra forma no tendrías? ¡Cuéntanoslo en los comentarios!

About these ads

Written by Juanlu001

21 de enero de 2014 a 19:00

Publicado en Preguntas

Etiquetado con , , ,

5 comentarios

Suscríbete a los comentarios mediante RSS.

  1. El problema es que cada uno de los valores de un array de `dtype = np.bool` ocupa él solito 8 bits enteros, es el equivalente del tipo de datos `bool` en C. Es decir, que acaba ocupando 8 veces más memoria de la estrictamente necesaria, justo lo que evita un bitset de C++ según el enlace que ponéis. Dependiendo de exactamente lo que quieras hacer, puede ser un factor muy limitante. No hay ninguna solución enteramente satisfactoria para manejar arrays de bits en numpy, aunque a veces se pueden encontrar soluciones usando `np.packbits` y `np.unpackbits`. Está el módulo `bitarray (https://pypi.python.org/pypi/bitarray/) pero no tengo experiancia con él, y no sé cómo de bien (o de mal) funcionará con numpy.

    Jaime Fernández del Río

    22 de enero de 2014 at 20:19

    • Muchas gracias por el comentario Jaime, porque esta es una limitación importante. He leído en StackOverflow:

      http://stackoverflow.com/questions/18066363/writing-numpy-bool-array-to-compact-file

      (donde, además, comentaste tú) que bitarray no está mal pero hace el algoritmo más lento.

      No obstante, en la documentación de NumPy explica que el tipo bool_ no hereda de int_, así que no termino de entender cuál es el motivo para que ocupe 8 bits. ¿Podrías aclarar esto? Viendo que hay muchas preguntas por el estilo en SO y que la gente lo demanda, ¿piensas que sería posible implementar un tipo booleano de 1 bit en NumPy?

      Juanlu001

      23 de enero de 2014 at 9:30

  2. […] Esta semana vamos con una pregunta de Gonzalo, que nos dice por email: Saludos. Últimamente he estado trabajado en python y me gusta mucho. En estos momentos estoy haciendo un algoritmo genético co…  […]

  3. Pues me viene muy bien el post y la referencia en los comentarios a bitarray. Estaba pensando en hacer algo de divulgación relacionada con cálculos en binario y quería hacer los ejemplos con un entorno “amigable” jeje

    El zombi de Schrödinger

    28 de enero de 2014 at 8:50

    • Así me gusta, Python a tope :D Si buscas hacer operaciones con números binarios te recomiendo que pruebes esto, eso sí:

      >>> bin(88)
      '0b1011000'
      >>> int('0b1011000',2)
      88
      >>> a = int('01100000',2)
      >>> b = 0b00100110
      >>> bin(a & b)
      '0b100000'
      >>> bin(a | b)
      '0b1100110'
      >>> bin(a ^ b)
      '0b1000110'
      
      

      (Adaptado de http://stackoverflow.com/a/1523581)

      ¡Un saludo!

      Juanlu001

      28 de enero de 2014 at 16:33


¡Deja un comentario!

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

Únete a otros 1.103 seguidores

%d personas les gusta esto: