You can use np.unpackbits:
a=np.array([-1,0,1]) # dtype is np.int32
You have to input your data as np.uint8 because that is the only data type supported by unpackbits:
bi = np.unpackbits(a[:,None].view(np.uint8), axis=1)
Original input data is 32bit, so you get 32 values per input element, crop accordingly (keeping in mind min/max values in a):
result = bi[:, :8]
array([[1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1]], dtype=uint8)
Edit:
This works well for small numbers like the one in the answer. If you need more than 8 bits, you should read the 1st 8 elements of bi and then the 16th to 8th elements. It's a bit messy.
For a more generic solution, just better flip the array view. And cropping before unpacking will give you a some performance improvement:
def int_to_bin(arr, n_bytes=1):
# arr is 1-D
arr_ = np.fliplr(arr[:, None].view(np.uint8))[:, -n_bytes:]
return np.unpackbits(arr_, axis=1)
You can crop the output further if you want, say, only 4 bits. This takes about 10 ms for one million arr of int32.