Search code examples
pythonnumpybit-manipulation

How to unpack bits from packbits results?


I am not familial with np.packbits and I want to perform a huge XOR operation by using it.

Here is my toy example:

import numpy as np

# Example arrays
u_values = np.array([[True, True, True, True, True, True, False, True, True, True],
                     [True, True, True, True, True, True, True, False, False, True],
                     [True, True, True, True, False, True, False, True, True, True],
                     [True, True, True, True, False, True, True, False, False, True],
                     [True, True, True, True, True, False, False, False, False, True],
                     [True, True, True, False, False, False, False, False, False, True],
                     [True, False, False, False, False, False, False, False, False, True],
                     [True, True, False, True, False, True, False, True, True, True]])

v_values = np.array([[True, True, True, True, True, True, False, True, True, True],
                     [True, False, True, False, True, True, True, False, False, True],
                     [True, True, True, True, False, True, False, True, True, True],
                     [True, False, True, True, False, False, True, False, False, True],
                     [True, True, False, True, True, False, False, False, False, True],
                     [True, True, True, False, False, True, False, False, False, True]])

I tried to use the following codes as below:

u_values_packed = np.packbits(u_values, axis=1)
v_values_packed = np.packbits(v_values, axis=1)
result_packed = u_values_packed[:, None, :] ^ v_values_packed[None, :, :]

result_packed = result_packed.reshape((-1, result_packed.shape[2]))
result_unpacked = np.unpackbits(result_packed, axis=1)
print(result_unpacked.shape) #(48,16)

I got the output shape (48,16) instead of (48,10).

How can I get the desired result so that I can perform XOR for each line of u_values with v_values resulting in a total dimension of (48,10)?

Here is the entired example output:

[[False False False False False False False False False False]
 [False  True False  True False False  True  True  True False]
 [False False False False  True False False False False False]
 [False  True False False  True  True  True  True  True False]
 [False False  True False False  True False  True  True False]
 [False False False  True  True False False  True  True False]
 [False False False False False False  True  True  True False]
 [False  True False  True False False False False False False]
 [False False False False  True False  True  True  True False]
 [False  True False False  True  True False False False False]
 [False False  True False False  True  True False False False]
 [False False False  True  True False  True False False False]
 [False False False False  True False False False False False]
 [False  True False  True  True False  True  True  True False]
 [False False False False False False False False False False]
 [False  True False False False  True  True  True  True False]
 [False False  True False  True  True False  True  True False]
 [False False False  True False False False  True  True False]
 [False False False False  True False  True  True  True False]
 [False  True False  True  True False False False False False]
 [False False False False False False  True  True  True False]
 [False  True False False False  True False False False False]
 [False False  True False  True  True  True False False False]
 [False False False  True False False  True False False False]
 [False False False False False  True False  True  True False]
 [False  True False  True False  True  True False False False]
 [False False False False  True  True False  True  True False]
 [False  True False False  True False  True False False False]
 [False False  True False False False False False False False]
 [False False False  True  True  True False False False False]
 [False False False  True  True  True False  True  True False]
 [False  True False False  True  True  True False False False]
 [False False False  True False  True False  True  True False]
 [False  True False  True False False  True False False False]
 [False False  True  True  True False False False False False]
 [False False False False False  True False False False False]
 [False  True  True  True  True  True False  True  True False]
 [False False  True False  True  True  True False False False]
 [False  True  True  True False  True False  True  True False]
 [False False  True  True False False  True False False False]
 [False  True False  True  True False False False False False]
 [False  True  True False False  True False False False False]
 [False False  True False  True False False False False False]
 [False  True  True  True  True False  True  True  True False]
 [False False  True False False False False False False False]
 [False  True  True False False  True  True  True  True False]
 [False False False False  True  True False  True  True False]
 [False False  True  True False False False  True  True False]]

Solution

  • numpy.packbits pads to a multiple of 8bits with 0, as documented. When doing unpack, there is no way for numpy to know what you aren't interested in these extra bits. You have to throw them away by hand:

    result_unpacked = np.unpackbits(result_packed, axis=1)[:, :10]