如何将 int8 数组转换为二进制并提取 python 中的位
how to convert int8 array to binary and extract bits in python
我有一个带有 int8 值的巨大 numpy 二维数组,我想将它转换为二进制值,提取一个或多个位,并仅使用 numpy 或类似库中的方法(例如numpy.where
或 np.bitwise_and
)。
例如:
array1 = [4, 128]
array_bits = [[0, 0, 0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0]]
#or ...
array_bits = ['00000100', '10000000']
#Extracting bit number 3 :
array_res = [1, 0]
我不太确定你为什么不想使用循环(老实说,我想不出你会用什么方法没有循环),但是这是我能找到的。
假设一个 int8 的二维数组:
nums = numpy.array([[random.randrange(255) for _ in range(20)],
[random.randrange(255) for _ in range(20)]], dtype=numpy.int8)
# Produces
array([[ 27, -111, 79, -116, -114, 59, -12, -44, -65, 66, 89,
-116, 0, 15, -31, 55, 54, -115, 115, 57],
[ 72, -57, -20, -88, -94, -112, -40, 55, 47, 120, 125,
-101, 117, -35, -29, -41, -68, -76, -11, -67]], dtype=int8)
您可以使用 numpy.ndarray.tostring
方法将其转换为字节数组:
>>> nums.tostring()
b'\x1b\x91O\x8c\x8e;\xf4\xd4\xbfBY\x8c\x00\x0f\xe176\x8ds9H\xc7\xec\xa8\xa2\x90\xd87/x}\x9bu\xdd\xe3\xd7\xbc\xb4\xf5\xbd'
然后您可以使用一些格式(和循环)将其转换为二进制字符串列表:
>>> bin_strs = [f'{b:08b}' for b in nums.tostring()]
# bin_strs
['00011011',
'10010001',
'01001111',
'10001100',
'10001110',
'00111011',
...
]
然后从 that,你可以使用切片和 int-casting 来获得特定的位,尽管你必须向后索引,因为第 0 位在右端:
>>> third_bits = [int(s[-3]) for s in bin_strs]
[0,
0,
1,
1,
1,
0,
...
]
虽然结果不是二维的,但你没有提到它很重要。
我们可以使用 np.unpackbits
来帮助解决这个问题。为了使这个功能起作用,我们需要先将数据转换为 np.uint8
。
>>> lst = [4, 128]
>>> arr = np.array(lst, dtype=np.uint8)
>>> bits = np.unpackbits(arr)
>>> bits
array([0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], dtype=uint8)
现在要访问“第 3 位”,我们将使用索引 5,因为一个字节中有 8 位,而您希望第 3 位到最后。然后使用步长8继续在同一位置获取下一个值的位。
>>> bits[5::8]
array([1, 0], dtype=uint8)
我有一个带有 int8 值的巨大 numpy 二维数组,我想将它转换为二进制值,提取一个或多个位,并仅使用 numpy 或类似库中的方法(例如numpy.where
或 np.bitwise_and
)。
例如:
array1 = [4, 128]
array_bits = [[0, 0, 0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0]]
#or ...
array_bits = ['00000100', '10000000']
#Extracting bit number 3 :
array_res = [1, 0]
我不太确定你为什么不想使用循环(老实说,我想不出你会用什么方法没有循环),但是这是我能找到的。
假设一个 int8 的二维数组:
nums = numpy.array([[random.randrange(255) for _ in range(20)],
[random.randrange(255) for _ in range(20)]], dtype=numpy.int8)
# Produces
array([[ 27, -111, 79, -116, -114, 59, -12, -44, -65, 66, 89,
-116, 0, 15, -31, 55, 54, -115, 115, 57],
[ 72, -57, -20, -88, -94, -112, -40, 55, 47, 120, 125,
-101, 117, -35, -29, -41, -68, -76, -11, -67]], dtype=int8)
您可以使用 numpy.ndarray.tostring
方法将其转换为字节数组:
>>> nums.tostring()
b'\x1b\x91O\x8c\x8e;\xf4\xd4\xbfBY\x8c\x00\x0f\xe176\x8ds9H\xc7\xec\xa8\xa2\x90\xd87/x}\x9bu\xdd\xe3\xd7\xbc\xb4\xf5\xbd'
然后您可以使用一些格式(和循环)将其转换为二进制字符串列表:
>>> bin_strs = [f'{b:08b}' for b in nums.tostring()]
# bin_strs
['00011011',
'10010001',
'01001111',
'10001100',
'10001110',
'00111011',
...
]
然后从 that,你可以使用切片和 int-casting 来获得特定的位,尽管你必须向后索引,因为第 0 位在右端:
>>> third_bits = [int(s[-3]) for s in bin_strs]
[0,
0,
1,
1,
1,
0,
...
]
虽然结果不是二维的,但你没有提到它很重要。
我们可以使用 np.unpackbits
来帮助解决这个问题。为了使这个功能起作用,我们需要先将数据转换为 np.uint8
。
>>> lst = [4, 128]
>>> arr = np.array(lst, dtype=np.uint8)
>>> bits = np.unpackbits(arr)
>>> bits
array([0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], dtype=uint8)
现在要访问“第 3 位”,我们将使用索引 5,因为一个字节中有 8 位,而您希望第 3 位到最后。然后使用步长8继续在同一位置获取下一个值的位。
>>> bits[5::8]
array([1, 0], dtype=uint8)