numpy имеет функцию packbits для этого.Он также поддерживает операции по осям:
In [3]: B = scipy.signbit(scipy.randn(1000,8)).astype("i1")
In [3]: B[0]
Out[3]: array([0, 1, 0, 0, 0, 1, 0, 0], dtype=int8)
In [4]: np.packbits(B[0])
Out[4]: array([68], dtype=uint8)
In [5]: %timeit np.packbits(B, axis=1)
10000 loops, best of 3: 37 µs per loop
, он работает для размеров int8 для больших размеров, которые вам нужно сместить, и / или
In [8]: x # multiple of 8
Out[8]: array([1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1], dtype=int8)
In [9]: r = np.packbits(x).astype(np.int32); r
Out[9]: array([171, 129], dtype=uint8)
In [10]: r[0] << 8 | r[1]
Out[10]: 33237
In [11]: sum(1<<i for i, b in enumerate(x[::-1]) if b)
Out[11]: 33237
, если x
не кратно 8 у васдополнить нулями