Saltar al contenido

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

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.org/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:
  • Utilizando el argumento dtype=bool para hacer una conversión explícita:
  • Utilizando el método astype:
  • Utilizando las funciones lógicas de NumPy:

(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!

5 comentarios en «¿Cómo trabajar con arrays de binarios en Python?»

  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.

    1. 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?

  2. Pingback: ¿Cómo trabajar con arrays de bina...

    1. Así me gusta, Python a tope 😀 Si buscas hacer operaciones con números binarios te recomiendo que pruebes esto, eso sí:
      [sourcecode]
      >>> 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’
      [/sourcecode]
      (Adaptado de http://stackoverflow.com/a/1523581)
      ¡Un saludo!

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

sixty six − = sixty

Pybonacci