将二进制Numpy数组转换为无符号整数

时间:2017-09-12 20:16:18

标签: python numpy

我有一个Numpy数组对象的长2D矩阵,其维数为n x 12.这是该矩阵的前10行:

b = ([[0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0]], dtype=uint8)

我想对这个数组做的是将它转换为无符号整数。据我所知,最快的方法是使用np.packbits函数。但是,此函数仅将8位打包为整数,而上面的数组在每行中包含12位。将上面的数组转换为无符号整数时我的期望是:

250, 248, 248, 250, 248, 248, 248, 248, 248, 248

有谁知道如何获得上述结果?我也通过上面的np.packbits尝试将位扩展到16(`.view('u2'),结果仍然不如我预期的那样。任何反馈都将不胜感激。谢谢。

2 个答案:

答案 0 :(得分:2)

我们可以将第一列4和最后8列分开,然后分别使用np.packbits。然后,缩放第一个切片以说明它们是其中最重要的,并添加第二个切片。

因此,实施将是 -

slice0 = np.packbits(b[:,:-8], axis=-1).astype(np.uint16) * 16
slice1 = np.packbits(b[:,-8:], axis=-1).astype(np.uint16)
out = slice0 + slice1

或者,将sum-redcutionmatrix-multiplication -

一起使用
b.dot(2**np.arange(b.shape[1]-1,-1,-1))

示例运行 -

In [1045]: b
Out[1045]: 
array([[0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0],
       [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0],
       [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0]], dtype=uint8)

In [1046]: slice0 = np.packbits(b[:,:-8], axis=-1).astype(np.uint16) * 16
      ...: slice1 = np.packbits(b[:,-8:], axis=-1).astype(np.uint16)
      ...: out = slice0 + slice1
      ...: 

In [1047]: out.ravel()
Out[1047]: array([1786,  248,  248,  250,  248,  248,  248,  248, 1272,  760])

In [1048]: b.dot(2**np.arange(b.shape[1]-1,-1,-1))
Out[1048]: array([1786,  248,  248,  250,  248,  248,  248,  248, 1272,  760])

答案 1 :(得分:1)

问题的一般解决方案是

from numpy import *
b = ([[0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
      [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0]])

def bin2int(x):
    y = 0
    for i,j in enumerate(x):
        y += j<<i
    return y


result = [bin2int(x[::-1]) for x in b]

所以你不必再担心多少比特了。