Sergey Sosnin Sergey Sosnin - 2 months ago 11
Python Question

numpy binary notation quick generation

Suppose, I have a

numpy
vector with
n
elements, so I'd like to encode numbers in this vector as a binary notation, so resulting shape will be
(n,m)
where
m
is
log2(maxnumber)
for example:

x = numpy.array([32,5,67])


Because max number I have is
67
, I need
numpy.ceil(numpy.log2(67)) == 7
bits to encode this vector, so shape of the result will be
(3,7)


array([[1, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 1, 0, 1],
[0, 1, 0, 0, 0, 0, 0]])


The problem rises because I have no quick way to move binary notation from

function
numpy.binary_repr
to numpy array. Now I have to iterate over result, and put each bit severally:

brepr = numpy.binary_repr(x[i],width=7)
j = 0
for bin in brepr:
X[i][j] = bin
j += 1


It's very timecost and stupid way, how to make it efficient?

Answer

Here us one way using np.unpackbits and broadcasting:

>>> max_size = np.ceil(np.log2(x.max())).astype(int)
>>> np.unpackbits(x[:,None].astype(np.uint8), axis=1)[:,-max_size:]
array([[0, 1, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 1, 0, 1],
       [1, 0, 0, 0, 0, 1, 1]], dtype=uint8)