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

Convert a byte array to single bits in a array [Python 3.5]

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

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 到 bin 的转换失败的原因吗?

最后,我的list操作有什么问题吗?

感谢您的帮助! :)

要解决 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']]

使用解包位:

>>> 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)

Unpacks elements of a uint8 array into a binary-valued output array.

Each element of myarray represents a bit-field that should be unpacked into a binary-valued output array. The shape of the output array is either 1-D (if axis is None) or the same shape as the input array with unpacking done along the axis specified.

我相当确定您的代码的问题在于您假设列表中每个项目中的 int 将变为 8 位(所以 2 将在您的假设中, return 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:]转为二进制(因为returns 0b1 for 1,需要用[2:]得到1 ).

最后一段代码是 "pad" 用额外的 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]]