如何使用Numpy创建给定无符号整数的二进制数字数组?

2024-10-03 23:22:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个介于0和3之间的数字数组,我想创建一个二进制数字的2D数组

在将来,我可能需要一个介于0到7或0到15之间的数字数组

当前我的数组定义如下:

a = np.array([[0], [1], [2], [3]], dtype=np.uint8)

我使用了numpyunpackbits函数:

b = np.unpackbits(a, axis=1)

结果是:

array([[0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 1],
       [0, 0, 0, 0, 0, 0, 1, 0],
       [0, 0, 0, 0, 0, 0, 1, 1]], dtype=uint8)

正如您所见,它创建了一个二维数组,其中列中有8个项目,而我正在查找2列二维数组

这是我想要的数组:

array([[0, 0],
       [0, 1],
       [1, 0],
       [1, 1]])

这与数据类型uint8有关吗

你的想法是什么


Tags: 项目函数定义np二进制数字数组array
3条回答

解决此问题的一种方法是通过简单的切片调整b以匹配所需的输出,类似于@GrzegorzSkibinski answer中所建议的:

import numpy as np


def gen_bits_by_val(values):
    n = int(max(values)).bit_length()
    return np.unpackbits(values, axis=1)[:, -n:].copy()


print(gen_bits_by_val(a))
# [[0 0]
#  [0 1]
#  [1 0]
#  [1 1]]

或者,您可以创建一个查找表,类似于@WarrenWeckesser answer中所建议的,使用以下命令:

import numpy as np


def gen_bits_by_num(n):
    values = np.arange(2 ** n, dtype=np.uint8).reshape(-1, 1)
    return np.unpackbits(values, axis=1)[:, -n:].copy()


bits2 = gen_bits_by_num(2)
print(bits2)
# [[0 0]
#  [0 1]
#  [1 0]
#  [1 1]]

允许所有类型的用途,例如:

bits4 = gen_bits_by_num(4)
print(bits4[[1, 3, 12]])
# [[0 0 0 1]
#  [0 0 1 1]
#  [1 1 0 0]]

编辑

考虑@PaulPanzer answer行:

return np.unpackbits(values, axis=1)[:, -n:]

已替换为:

return np.unpackbits(values, axis=1)[:, -n:].copy()

哪个内存效率更高

它本可以被以下内容取代:

return np.unpackbits(values << (8 - n), axis=1, count=n)

具有类似的效果

您可以截断b以仅保留自第一列1起的列:

b=b[:, int(np.argwhere(b.max(axis=0)==1)[0]):]

您可以使用count关键字。它从右侧剪切,因此在应用unpackbits之前还必须移位位

b = np.unpackbits(a<<6, axis=1, count=2)
b
# array([[0, 0],
#        [0, 1],
#        [1, 0],
#        [1, 1]], dtype=uint8)

这将生成一个“干净”数组:

b.flags
#  C_CONTIGUOUS : True
#  F_CONTIGUOUS : False
#  OWNDATA : True
#  WRITEABLE : True
#  ALIGNED : True
#  WRITEBACKIFCOPY : False
#  UPDATEIFCOPY : False

相反,切片unpackbits的完整8列输出在某种意义上是内存泄漏,因为只要切片存在,被丢弃的列就会留在内存中

相关问题 更多 >