2

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
1
  • 1
    I think the last is 516 (512+4) and not 518. Commented Mar 31, 2022 at 22:39

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.