Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Convert a numpy bool array to int

I have a numpy array (dtype bool) representing an array of bits. For example, the array np.array([True, False, False], dtype=bool) represents the number 4 (indeed, bin(4) == 0b100).

I would like to convert the numpy array to an integer (4 in the previous example).

So far I’ve tried with an iterative approach:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

bits = np.array([True, False, False], dtype=bool)
n = 0
for bit in bits:
    n = (n << 1) | bit

This approach does work, but I would prefer something that does not iterate over every element of the array, possibly a numpy built-in method.

I also tried using numpy.packbits (together with numpy.pad, because packbits always automatically pad to the right, and not to the left):

bits = np.array([True, False, False], dtype=bool)
n = np.packbits(np.pad(bits, ((8 - len(bits) % 8) % 8, 0))).item()

This approach only works for arrays with 8 or less elements. Indeed, if you try to use a longer array you end up having multiple results (because apparently packbits not only pads to the right but also converts every single byte to a number):

bits = np.array(
    [True, False, False, False, False, False, False, False, False],
    dtype=bool,
)
n = np.packbits(np.pad(bits, ((8 - len(bits) % 8) % 8, 0)))
print(n) # this prints [1 0], but I need it to return 256

Expected behavior:

np.array([True, True], dtype=bool) --> 3
np.array([True, True, False], dtype=bool) --> 6
np.array([True, False, False, True, True], dtype=bool) --> 19
np.array([True, False, False, False, False,
          False, False, True, False, False], dtype=bool) --> 516

>Solution :

You can solve this problem by generating the power of two starting from the biggest one (eg. [16, 8, 4, 2, 1]), and then multiply this by bits before doing the final sum:

powers = 1 << np.arange(bits.size, dtype=np.uint64)[::-1]
result = np.sum(powers * bits)

This is equivalent of doing: 2**n * bits[0] + 2**(n-1) * bits[1] + ... + 2**0 * bits[n].
Note that the final value needs to fit in 64 bits.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading