Numpy 有一个库函数 ,np.unpackbits
它将 a 解包uint8
为长度为 8 的位向量。是否有相应快速的方法来解包更大的数字类型?例如uint16
或uint32
。我正在研究一个涉及数字之间频繁转换、数组索引及其位向量表示的问题,瓶颈是我们的打包和解包函数。
问问题
9060 次
4 回答
19
view
你可以这样做unpackbits
输入:
unpackbits(arange(2, dtype=uint16).view(uint8))
输出:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0]
因为a = arange(int(1e6), dtype=uint16)
这在我的机器上非常快,大约 7 毫秒
%%timeit
unpackbits(a.view(uint8))
100 loops, best of 3: 7.03 ms per loop
至于字节顺序,您必须查看http://docs.scipy.org/doc/numpy/user/basics.byteswapping.html并根据您的需要应用建议。
于 2013-08-18T06:16:47.323 回答
16
这是我使用的解决方案:
def unpackbits(x, num_bits):
if np.issubdtype(x.dtype, np.floating):
raise ValueError("numpy data type needs to be int-like")
xshape = list(x.shape)
x = x.reshape([-1, 1])
mask = 2**np.arange(num_bits, dtype=x.dtype).reshape([1, num_bits])
return (x & mask).astype(bool).astype(int).reshape(xshape + [num_bits])
这是一个完全矢量化的解决方案,适用于任何维度的 ndarray,并且可以解压缩任何你想要的位。
于 2018-07-25T00:31:30.690 回答
3
我也没有找到任何函数,但也许使用 Python 的内置 struct.unpack 可以帮助使自定义函数比移位和更长的 uint 更快(注意我使用的是 uint64)。
>>> import struct
>>> N = np.uint64(2 + 2**10 + 2**18 + 2**26)
>>> struct.unpack('>BBBBBBBB', N)
(2, 4, 4, 4, 0, 0, 0, 0)
这个想法是将这些转换为 uint8,使用 unpackbits,连接结果。或者,根据您的应用程序,使用结构化数组可能更方便。
还有内置的 bin() 函数,它产生 0 和 1 的字符串,但我不确定它有多快,它也需要后处理。
于 2013-08-18T06:13:18.743 回答
0
这适用于任意 uint 的任意数组(即也适用于多维数组以及大于 uint8 最大值的数字)。
它在位数上循环,而不是在数组元素的数量上循环,所以它相当快。
def my_ManyParallel_uint2bits(in_intAr,Nbits):
''' convert (numpyarray of uint => array of Nbits bits) for many bits in parallel'''
inSize_T= in_intAr.shape
in_intAr_flat=in_intAr.flatten()
out_NbitAr= numpy.zeros((len(in_intAr_flat),Nbits))
for iBits in xrange(Nbits):
out_NbitAr[:,iBits]= (in_intAr_flat>>iBits)&1
out_NbitAr= out_NbitAr.reshape(inSize_T+(Nbits,))
return out_NbitAr
A=numpy.arange(256,261).astype('uint16')
# array([256, 257, 258, 259, 260], dtype=uint16)
B=my_ManyParallel_uint2bits(A,16).astype('uint16')
# array([[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
# [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
# [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
# [1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]], dtype=uint16)
于 2018-03-02T16:16:02.633 回答