将字节数组转换为数组中的单个位[Python 3.5]

时间:2016-09-27 07:25:41

标签: python arrays hex bit

我正在寻找一个转换我的字节数组的操作:

mem = b'\x01\x02\xff'

就像这样:

[ [0 0 0 0 0 0 0 1]
  [0 0 0 0 0 0 1 0]
  [1 1 1 1 1 1 1 1] ]

这些是我尝试的操作:

import numpy as np

mem = b'\x01\x02\xff' #define my input
mem = np.fromstring(mem, dtype=np.uint8) #first convert to int

#print(mem) give me "[  1   2 255]" at this piont

mem = np.array(['{0:08b}'.format(mem[b]) for b in mem]) #now convert to bin
data= np.array([list(mem[b]) for b in mem]) #finally convert to single bits

print(data)

此代码将在第4行崩溃。IndexError: index 255 is out of bounds for axis 0 with size 9 否则,它会在第5行崩溃。IndexError: too many indices for array

这些是我的问题:

为什么从十六进制转换为int后空格数不同?

这是我下一次从int到bin的转换失败的原因吗?

最后,我的list操作出了什么问题?

感谢您的帮助! :)

4 个答案:

答案 0 :(得分:2)

使用unpackbits:

>>> import numpy as np
>>> mem = b'\x01\x02\xff'
>>> x = np.fromstring(mem, dtype=np.uint8)
>>> np.unpackbits(x).reshape(3,8)
array([[0, 0, 0, 0, 0, 0, 0, 1],
       [0, 0, 0, 0, 0, 0, 1, 0],
       [1, 1, 1, 1, 1, 1, 1, 1]], dtype=uint8)

文档

来自help(np.unpackbits)

  

<强> unpackbits (...)
  unpackbits(myarray,axis = None)

     

将uint8数组的元素解包为二进制值输出数组。

     

myarray的每个元素代表一个应该解压缩的位字段   到二进制值输出数组。输出数组的形状也是   1-D(如果axis为None)或与解包的输入数组相同的形状   沿着指定的轴完成。

答案 1 :(得分:0)

要解决IndexError,您可以使用numpy.ndindex

import numpy as np

mem = b'\x01\x02\xff' #define my input
mem = np.fromstring(mem, dtype=np.uint8) #first convert to int

#print(mem) give me "[  1   2 255]" at this piont
mem=np.array(['{0:07b}'.format(mem[b]) for b in np.ndindex(mem.shape)])

data= np.array([list(mem[b]) for b in np.ndindex(mem.shape)]) #finally convert to single bits

print(data)

<强>输出:

[['0', '0', '0', '0', '0', '0', '1'] ['0', '0', '0', '0', '0', '1', '0']
 ['1', '1', '1', '1', '1', '1', '1', '1']]

答案 2 :(得分:0)

我相当确定您的代码存在的问题是,您认为列表中每个项目中的int将变为8位(因此2将会出现在您的代码中假设,返回00000010)。但它并没有(2 = 10),这会搞砸你的代码。

对于你的最后两行,我认为这应该没问题:

data = [list(str(bin(x))[2:]) for x in mem]
for a in range(len(data)):
    while len(data[a]) < 8:
        data[a] = "0" + data[a]

str(bin(x))[2:]会转换为二进制文件(因为它会为0b1返回1,您需要使用[2:]来获取1

最后一块代码是&#34; pad&#34;用额外的0打开你的号码。

答案 3 :(得分:0)

mem = b'\x01\x02\xff'
[[int(digit) for digit in "{0:08b}".format(byte)] for byte in mem]

输出:

[[0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 1, 0], [1, 1, 1, 1, 1, 1, 1, 1]]