6

I´ve got a 3D numpy bit array, I need to pack them along the third axis. So exactly what numpy.packbits does. But unfortunately it packs it only to uint8, but I need more data, is there a similar way to pack it to uint16 or uint32?

ZZM
  • 63
  • 1
  • 6

1 Answers1

11

Depending on your machine's endianness it is either a matter of simple view casting or of byte swapping and then view casting:

>>> a = np.random.randint(0, 2, (4, 16))
>>> a
array([[1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0],
       [0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1],
       [0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1],
       [1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1]])
>>> np.packbits(a.reshape(-1, 2, 8)[:, ::-1]).view(np.uint16)
array([53226, 23751, 25853, 64619], dtype=uint16)

# check:
>>> [bin(x + (1<<16))[-16:] for x in _]
['1100111111101010', '0101110011000111', '0110010011111101', '1111110001101011']

You may have to reshape in the end.

Paul Panzer
  • 51,835
  • 3
  • 54
  • 99
  • One may also use [np.ndarray.byteswap](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.byteswap.html) to handle little endianness – Alexander Soare Apr 06 '21 at 10:57