5

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?

Sergey Sosnin
  • 1,313
  • 13
  • 30

2 Answers2

4

Here is 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)
Mazdak
  • 105,000
  • 18
  • 159
  • 188
1

You can use numpy byte string.

For the case you have in hand:

res = numpy.array(len(x),dtype='S7')
for i in range(len(x)):
    res[i] = numpy.binary_repr(x[i])

Or more compactly

res = numpy.array([numpy.binary_repr(val) for val in x])
innoSPG
  • 4,588
  • 1
  • 29
  • 42