189

I use Scilab, and want to convert an array of booleans into an array of integers:

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

In Scilab I can use:

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

or even just multiply it by 1:

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

Is there a simple command for this in Python, or would I have to use a loop?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Kwolf
  • 2,001
  • 2
  • 12
  • 4
  • Are you asking for a way to convert a boolean array into an integer one without scipy, numpy and the like? – Sukrit Kalra Jul 06 '13 at 19:11
  • There's a separate way of formatting code. You don't have to use blockquote. It's done by indenting, and the curly braces button above the question editor will do it for you. Check it out. – Marcin Jul 06 '13 at 19:11
  • Sukrit, I don't care if i have to use scipy, numpy or any other python module package. – Kwolf Jul 06 '13 at 20:38

6 Answers6

236

Numpy arrays have an astype method. Just do y.astype(int).

Note that it might not even be necessary to do this, depending on what you're using the array for. Bool will be autopromoted to int in many cases, so you can add it to int arrays without having to explicitly convert it:

>>> x
array([ True, False,  True], dtype=bool)
>>> x + [1, 2, 3]
array([2, 2, 4])
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • 9
    yes, i can also type x*1...and it does the same thing scilab does....*feels like dumbass now*.. thank you everyone for you help!....although the answer was right in my question, i really liked getting the variety of answers and seeing all the different ways to do it. Really opened my mind regarding python. – Kwolf Jul 06 '13 at 20:49
  • 1
    Re boolean arrays being autopromoted: unfortunately, numpy is not consistent with this. Try subtracting two boolean arrays, and you get a TypeError and a deprecation message. – oulenz Mar 16 '20 at 09:55
74

The 1*y method works in Numpy too:

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

If you are asking for a way to convert Python lists from Boolean to int, you can use map to do it:

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

Or using list comprehensions:

>>> testList
[False, False, True, True]
>>> [int(elem) for elem in testList]
[0, 0, 1, 1]
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Sukrit Kalra
  • 33,167
  • 7
  • 69
  • 71
  • 1
    so, `y = 1 if x else 0` is the same as `y = 1 if x>0 else 0` and the same as `if x: y = 1 ""NEXT LINE"" else: y = 0`....how did you learn those tricks, i didn't see it in the _if statement_ documentation? – Kwolf Jul 06 '13 at 23:11
  • No. `y=1 if x else 0` is not the same as `y=1 if x>0 else 0`, since the latter doesn't take the negative numbers into consideration. This is just what Python defines as `True` or `False`, these are all in the documentation. – Sukrit Kalra Jul 07 '13 at 04:26
  • `y.astype(int)` is 2.5x faster than `1*y` or `0+y`. https://perfpy.com/160 – Maxim Egorushkin Nov 17 '22 at 04:50
37

Using numpy, you can do:

y = x.astype(int)

If you were using a non-numpy array, you could use a list comprehension:

y = [int(val) for val in x]
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
cjm
  • 3,703
  • 1
  • 16
  • 18
20

Most of the time you don't need conversion:

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

The right way to do it is:

yourArray.astype(int)

or

yourArray.astype(float)
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Gioelelm
  • 2,645
  • 5
  • 30
  • 49
10

A funny way to do this is

>>> np.array([True, False, False]) + 0 
np.array([1, 0, 0])
Tomas G.
  • 3,784
  • 25
  • 28
3

I know you asked for non-looping solutions, but the only solutions I can come up with probably loop internally anyway:

map(int,y)

or:

[i*1 for i in y]

or:

import numpy
y=numpy.array(y)
y*1
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
bsoist
  • 775
  • 3
  • 10
  • yes, the looping is slow. from what i've read, if you need to do some time critical crunching you should call c from python. Do you know any references for doing this? also, thank you for your help. surprised how fast everyone responded! – Kwolf Jul 06 '13 at 20:54