Home > Blockchain >  packing a numpy array of ones and zeroes into a array of 32 bit values
packing a numpy array of ones and zeroes into a array of 32 bit values

Time:11-07

i have a 1-d array of 1's and 0's in a numpy integer array, i want to pack these values in a array of unsigned 32 bit integer values.

for example, lets say the integer array is

{0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1

i want to convert it to this

{0b01111111111000000000000111111111,0b11111111111111110000111111111111}

how can i achieve this ? thanks in advance

CodePudding user response:

I would use numpy.packbits and numpy.frombuffer. Result is missing first zero though, but mcsoini says it is expected though - the zero is there, just is not printed.

import numpy as np

data = [0,1,1,1,1,1,1,1,1,1,
        1,0,0,0,0,0,0,0,0,0,
        0,0,0,1,1,1,1,1,1,1,
        1,1,1,1,1,1,1,1,1,1,
        1,1,1,1,1,1,1,1,0,0,
        0,0,1,1,1,1,1,1,1,1,
        1,1,1]

result = np.frombuffer(np.packbits(data).tobytes(), dtype=np.uint32)
print([bin(item) for item in result])
['0b11111111000000011110000001111111', '0b11111110000011111111111111111111']

CodePudding user response:

I think your best bet is to go through strings:

d = [0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1, 0]

[bin(int("".join(map(str, integer)), 2)) 
 for integer in np.array_split(d, len(d) / 32)]

# Out:
# ['0b1111111111000000000000111111111', '0b11111111111111110000111111111110']

I added a zero to the input data to make the length a multiple of 32.

CodePudding user response:

You use bitshift to move the digit to the correct binary index. Then just accumulate the values.

(d << np.arange(len(d))).sum()

Here a more extensive version:

# first, extend to a multiple of 32
d = np.append(d, np.zeros(len(d) & 31, dtype=d.dtype))
# reshape into Nx32
d = d.reshape((-1, 32))
# broadcasted bitshift
bits = d << np.arange(32, dtype=d.dtype))
# accumulate into one value per row
bits = bits.sum(axis=1)
  • Related