gpt4 book ai didi

python - numpy 将 int 解析为位分组

转载 作者:太空宇宙 更新时间:2023-11-03 14:21:09 25 4
gpt4 key购买 nike

我有一个 np.arraynp.uint8

a = np.array([randint(1,255) for _ in range(100)],dtype=np.uint8)

我想把它分成低半字节和高半字节

我可以得到低半字节

low = np.bitwise_and(a,0xF)

我可以用

high = np.bitwise_and(np.right_shift(a,4),0xF)

有没有办法做类似的事情

>>> numpy.keep_bits(a,[(0,3),(4,7)])
numpy.array([
[low1,high1],
[low2,high2],
...
[lowN,highN]
])

我什至不确定这会被称为什么......但我想也许一些 NumPy 的大师会知道一个很酷的方法来做到这一点(实际上我正在寻找用 uint32 和更多不同的半字节来做到这一点

基本上类似于 struct.unpack 但用于矢量化 numpy 操作

编辑:我使用了下面已接受答案的修改版本

这是我给感兴趣的人的最终代码

def bitmask(start,end):
"""
>>> bitmask(0,2) == 0b111
>>> bitmask(3,5) == 0b111000

:param start: start bit
:param end: end bit (unlike range, end bit is inclusive)
:return: integer bitmask for the specified bit pattern
"""
return (2**(end+1-start)-1)<<start

def mask_and_shift(a,mask_a,shift_a):
"""

:param a: np.array
:param mask_a: array of masks to apply (must be same size as shift_a)
:param shift_a: array of shifts to apply (must be same size as mask_a)
:return: reshaped a, that has masks and shifts applied
"""
masked_a = numpy.bitwise_and(a.reshape(-1,1), mask_a)
return numpy.right_shift(masked_a,shift_a)

def bit_partition(rawValues,bit_groups):
"""
>>> a = numpy.array([1,15,16,17,125,126,127,128,129,254,255])
>>> bit_partition(a,[(0,2),(3,7)])
>>> bit_partition(a,[(0,2),(3,5),(6,7)])

:param rawValues: np.array of raw values
:param bit_groups: list of start_bit,end_bit values for where to bit twiddle
:return: np.array len(rawValues)xlen(bit_groups)
"""
masks,shifts = zip(*[(bitmask(s,e),s) for s,e in bit_groups])
return mask_and_shift(rawValues,masks,shifts)

最佳答案

一个单行代码,使用广播,用于四位低位和高位半字节:

In [38]: a
Out[38]: array([ 1, 15, 16, 17, 127, 128, 255], dtype=uint8)

In [39]: (a.reshape(-1,1) & np.array([0xF, 0xF0], dtype=np.uint8)) >> np.array([0, 4], dtype=np.uint8)
Out[39]:
array([[ 1, 0],
[15, 0],
[ 0, 1],
[ 1, 1],
[15, 7],
[ 0, 8],
[15, 15]], dtype=uint8)

要概括这一点,请将硬编码值 [0xF, 0xF0][0, 4] 替换为适当的位掩码和移位。例如,要将值分成三组,包含最高两位,然后是其余两组,每组三位,您可以这样做:

In [41]: masks = np.array([0b11000000, 0b00111000, 0b00000111], dtype=np.uint8)

In [42]: shifts = np.array([6, 3, 0], dtype=np.uint8)

In [43]: a
Out[43]: array([ 1, 15, 16, 17, 127, 128, 255], dtype=uint8)

In [44]: (a.reshape(-1,1) & np.array(masks, dtype=np.uint8)) >> np.array(shifts, dtype=np.uint8)
Out[44]:
array([[0, 0, 1],
[0, 1, 7],
[0, 2, 0],
[0, 2, 1],
[1, 7, 7],
[2, 0, 0],
[3, 7, 7]], dtype=uint8)

关于python - numpy 将 int 解析为位分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27697340/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com