Home > Back-end >  Convert a numpy bool array to int
Convert a numpy bool array to int

Time:04-01

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:

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

CodePudding user response:

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.

CodePudding user response:

Try using numpy.logspace:

import numpy as np
bits = np.array([True, False, False, False, False, False, False, False, False],dtype=bool,)
bits=bits[::-1]
result = np.sum(np.logspace(0, bits.size-1, num=bits.size, base=2) * bits, dtype=np.int)

This outputs:

print(result)
256
  • Related