Cómo convertir una matriz booleana en una matriz int

129

Yo uso Scilab, y quiero convertir una matriz de booleanos en una matriz de enteros:

>>> x = np.array([4, 3, 2, 1])
>>> y = 2 >= x
>>> y
array([False, False,  True,  True], dtype=bool)

En Scilab puedo usar:

>>> bool2s(y)
0.    0.    1.    1.  

o incluso simplemente multiplíquelo por 1:

>>> 1*y
0.    0.    1.    1.  

¿Hay un comando simple para esto en Python, o tendría que usar un bucle?

Kwolf
fuente
¿Está pidiendo una manera de convertir una matriz booleana en una entera sin scipy, numpy y similares?
Sukrit Kalra
Hay una forma separada de formatear el código. No tiene que usar blockquote. Se realiza mediante sangría, y el botón de llaves encima del editor de preguntas lo hará por usted. Echale un vistazo.
Marcin
Sukrit, no me importa si tengo que usar scipy, numpy o cualquier otro paquete de módulos de python.
Kwolf

Respuestas:

167

Las matrices Numpy tienen un astypemétodo. Solo hazlo y.astype(int).

Tenga en cuenta que puede que ni siquiera sea necesario hacer esto, dependiendo de para qué esté usando la matriz. Bool se promocionará automáticamente a int en muchos casos, por lo que puede agregarlo a matrices int sin tener que convertirlo explícitamente:

>>> x
array([ True, False,  True], dtype=bool)
>>> x + [1, 2, 3]
array([2, 2, 4])
BrenBarn
fuente
55
sí, también puedo escribir x * 1 ... y hace lo mismo que scilab ... * se siente como un idiota ahora * ... ¡gracias a todos por su ayuda! ... aunque la respuesta fue correcta en mi pregunta, realmente me gustó obtener la variedad de respuestas y ver todas las diferentes formas de hacerlo. Realmente abrí mi mente con respecto a Python.
Kwolf
Las matrices booleanas re autopromocionadas: desafortunadamente, numpy no es consistente con esto. Intente restar dos matrices booleanas y obtendrá un Error de tipo y un mensaje de desaprobación.
oulenz
52

El 1*ymétodo también funciona en Numpy:

>>> import numpy as np
>>> x = np.array([4, 3, 2, 1])
>>> y = 2 >= x
>>> y
array([False, False,  True,  True], dtype=bool)
>>> 1*y                      # Method 1
array([0, 0, 1, 1])
>>> y.astype(int)            # Method 2
array([0, 0, 1, 1]) 

Si está pidiendo una forma de convertir listas de Python de booleano a int, puede usarlo mappara hacerlo:

>>> testList = [False, False,  True,  True]
>>> map(lambda x: 1 if x else 0, testList)
[0, 0, 1, 1]
>>> map(int, testList)
[0, 0, 1, 1]

O usando listas de comprensión:

>>> testList
[False, False, True, True]
>>> [int(elem) for elem in testList]
[0, 0, 1, 1]
Sukrit Kalra
fuente
entonces, y = 1 if x else 0 es lo mismo y = 1 if x>0 else 0y lo mismo que if x: y = 1 ""NEXT LINE"" else: y = 0... ¿cómo aprendiste esos trucos, no lo vi en la documentación de la declaración if ?
Kwolf
No, y=1 if x else 0no es lo mismo y=1 if x>0 else 0, ya que este último no tiene en cuenta los números negativos. Esto es exactamente lo que Python define como Trueo False, todos están en la documentación.
Sukrit Kalra
24

Usando numpy, puedes hacer:

y = x.astype(int)

Si estaba usando una matriz no numpy, podría usar una lista de comprensión :

y = [int(val) for val in x]
cjm
fuente
14

La mayoría de las veces no necesita conversión:

>>>array([True,True,False,False]) + array([1,2,3,4])
array([2, 3, 3, 4])

La forma correcta de hacerlo es:

yourArray.astype(int)

o

yourArray.astype(float)
Gioelelm
fuente
3

Sé que solicitó soluciones sin bucle, pero las únicas soluciones que puedo encontrar probablemente se repitan internamente de todos modos:

map(int,y)

o:

[i*1 for i in y]

o:

import numpy
y=numpy.array(y)
y*1
bsoist
fuente
Sí, el bucle es lento. por lo que he leído, si necesita hacer algo de tiempo crítico, debe llamar a c desde python. ¿Conoces alguna referencia para hacer esto? Además, gracias por tu ayuda. ¡sorprendido de lo rápido que respondieron todos!
Kwolf
2

Una forma divertida de hacer esto es

>>> np.array([True, False, False]) + 0 
np.array([1, 0, 0])
Thomas G.
fuente