2013-08-18 32 views
8

Numpy具有库函数np.unpackbits,该函数将uint8解压缩为长度为8的位向量。是否有相应的快速方法来解压缩较大的数值类型?例如。 uint16uint32。我正在研究一个涉及数字间频繁转换,数组索引和位矢量表示的问题,瓶颈是我们的包和解包函数。如何提取较大的数字Numpy数据类型的位

+0

您可以创建一个新的'ndarray'作为缓冲区和'uint8'的一个dtype。不过,我不确定处理字节顺序的最佳方式是什么。 http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html和http://docs.scipy.org/doc/numpy/user/basics.byteswapping.html可能会有所帮助。 – user2357112

回答

7

你可以用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并根据您的需要应用建议。

+0

很好的答案,谢谢! – Cardano

+0

乐意帮忙:) –

+0

这只适用于“uint8”范围内的整数。例如。 ''np.unpackbits(np.array([2 ** 17],dtype =“uint16”)。view(“uint8”))''将返回一个零数组。 –

1

我还没有找到任何函数,但也许使用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,连接结果。或者,根据您的应用程序,使用structured arrays可能会更方便。

还有内置的bin()函数,它产生0和1的字符串,但我不知道它有多快,它也需要后处理。

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)