[英]Python/Numpy - Extracting Bits of Bytes
我有numpy.frombuffer()
数组形式的 8 个字节的数据。 我需要将第 10-19 位放入变量,将第 20-29 位放入变量。 如何使用 Python 提取跨字节的位? 我读过关于位移的文章,但我不清楚这是否是这样做的方法。
通过索引正确的字节来单独获取每个位,然后屏蔽正确的位。 然后,您可以移位和添加以从位构建新数字。
data = b'abcdefgh' #8 bytes of data
def bit_slice(data, start, stop):
out = 0
for i in range(start, stop):
byte_n = i//8
byte_bit = i%8
byte_mask = 1<<byte_bit
bit = bool(data[byte_n] & byte_mask)
out = out*2 + bit #multiply by 2 is equivalent to shift. Then add the new bit
return out
回复:评论
每次我们想为我们的数字添加一个新位时,如下所示:
10110
101101
我们必须将前五位移位,然后根据下一位的值加 1 或 0。 向左移动每个数字高一位,这在二进制中意味着乘以 2。在十进制中,将一个数字移一位意味着乘以 10。当将新位添加到我们的数字时,我们正在累加我只是乘以 2使用右移运算符只是为了表明它是另一种选择。 创建字节掩码时,我确实使用了右移运算符 ( <<
)。 它的工作原理是将 1 移动几个位置,所以我最终得到一个在正确位置有一个 1 的字节,当我用有问题的字节“和”它时,我只得到我想要索引的单个位:
1<<3 = 00001000
1<<5 = 00100000
1<<0 = 00000001
1<<7 = 10000000
然后应用掩码以获得我们想要的位:
10011011 #一个字节的数据
00100000 #bit 掩码为 32 位
_________&
00 0 00000
#bit 在 32 的位置是 0
10011011 #一个字节的数据
00010000 #bit 掩码为 16 位
_________&
000 1 0000
#bit 在 16 的位置是 1
应用掩码后,如果所选位为 0,则整个数字将始终为 0。如果所选位为 1,则数字将始终大于 0。对该结果调用bool
等效于:
if data[byte_n] & byte_mask > 0:
bit = 1
else:
bit = 0
... 因为解释为整数的布尔值只是一个 1 或一个 0。
根据您的数据类型,您可能需要稍微修改这个 numpy 解决方案:
a = np.frombuffer(b'\x01\x02\x03\x04\x05\x06\x07\x08', dtype=np.uint8)
#array([1, 2, 3, 4, 5, 6, 7, 8], dtype=uint8)
拆包位:
first = np.unpackbits(a)[10:20]
#array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0], dtype=uint8)
如果您需要重新打包这些位:
first_packed = np.packbits(first)
array([8, 0], dtype=uint8)
请注意,python 是基于 0 的索引,如果您想要第np.unpackbits(a)[9:19]
元素,请将上述索引调整为np.unpackbits(a)[9:19]
。
其他情况类似:
second = np.unpackbits(a)[20:30]
#array([0, 0, 1, 1, 0, 0, 0, 0, 0, 1], dtype=uint8)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.