Como converter uma matriz booleana em uma matriz int

129

Eu uso o Scilab e quero converter uma matriz de booleanos em uma matriz de números inteiros:

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

No Scilab eu posso usar:

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

ou mesmo multiplicá-lo por 1:

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

Existe um comando simples para isso em Python, ou eu teria que usar um loop?

Kwolf
fonte
Você está solicitando uma maneira de converter uma matriz booleana em uma matriz inteira sem scipy, numpy e similares?
58613 Sukrit Kalra
Existe uma maneira separada de formatar o código. Você não precisa usar a citação em bloco. É feito recuando e o botão de chaves acima do editor de perguntas fará isso por você. Confira.
Marcin
Sukrit, eu não me importo se eu tiver que usar scipy, numpy ou qualquer outro pacote de módulo python.
Kwolf

Respostas:

167

Matrizes numpy têm um astypemétodo Apenas faça y.astype(int).

Observe que pode nem ser necessário fazer isso, dependendo do uso da matriz. O bool será promovido automaticamente para int em muitos casos, portanto, você pode adicioná-lo às matrizes int sem precisar convertê-lo explicitamente:

>>> x
array([ True, False,  True], dtype=bool)
>>> x + [1, 2, 3]
array([2, 2, 4])
BrenBarn
fonte
5
sim, eu também posso digitar x * 1 ... e faz a mesma coisa que o scilab ... * parece idiota agora * .. obrigado a todos por sua ajuda! .... embora a resposta esteja certa na minha pergunta, eu realmente gostei de obter a variedade de respostas e ver todas as diferentes maneiras de fazer isso. Realmente abriu minha mente sobre python.
Kwolf
Matrizes re booleanas sendo promovidas automaticamente: infelizmente, numpy não é consistente com isso. Tente subtrair duas matrizes booleanas e você receberá um TypeError e uma mensagem de reprovação.
oulenz 16/03
52

O 1*ymétodo também funciona no 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]) 

Se você está procurando uma maneira de converter listas Python de booleano em int, pode usar map:

>>> 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]

Ou usando a compreensão da lista:

>>> testList
[False, False, True, True]
>>> [int(elem) for elem in testList]
[0, 0, 1, 1]
Sukrit Kalra
fonte
então, y = 1 if x else 0 é o mesmo y = 1 if x>0 else 0e o mesmo que if x: y = 1 ""NEXT LINE"" else: y = 0.... como você aprendeu esses truques, eu não vi isso na documentação da instrução if ?
Kwolf
Não. Não y=1 if x else 0é o mesmo que y=1 if x>0 else 0, uma vez que este último não leva em consideração os números negativos. Isso é exatamente o que Python define como Trueou False, tudo isso está na documentação.
21813 Sukrit Kalra
24

Usando numpy, você pode fazer:

y = x.astype(int)

Se você estivesse usando uma matriz não numpy, poderia usar uma compreensão de lista :

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

Na maioria das vezes você não precisa de conversão:

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

A maneira correta de fazer isso é:

yourArray.astype(int)

ou

yourArray.astype(float)
Gioelelm
fonte
3

Sei que você pediu soluções sem loop, mas as únicas soluções que posso encontrar provavelmente fazem loop internamente de qualquer maneira:

map(int,y)

ou:

[i*1 for i in y]

ou:

import numpy
y=numpy.array(y)
y*1
bsoist
fonte
sim, o loop é lento. pelo que li, se você precisar fazer algum processamento crítico de tempo, chame c de python. Você conhece alguma referência para fazer isso? Além disso, obrigado por sua ajuda. surpreendeu a rapidez com que todos responderam!
Kwolf
2

Uma maneira engraçada de fazer isso é

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