将整数数组转换为二进制表示矩阵

时间:2019-07-10 12:04:26

标签: python numpy

给出一维整数数组,例如:

[1, 0, -1]

寻找一个二进制表示矩阵,期望的输出:

[[0 1], [0 0], [1 1]]

可能使用np.binary_repr,且具有固定的宽度。当前np.binary_repr会返回一个字符串,一次只能应用于一个数字。

tobin = np.vectorize(np.binary_repr)
tobin(np.arange(4))
# ['0000' '0001' '0010' '0011']

2 个答案:

答案 0 :(得分:1)

您可以使用np.unpackbits

a=np.array([-1,0,1]) # dtype is np.int32

您必须将数据输入为np.uint8,因为这是拆包支持的唯一数据类型:

bi = np.unpackbits(a[:,None].view(np.uint8), axis=1)

原始输入数据为32位,因此每个输入元素可获得32个值,并相应地裁剪(请注意a中的最小值/最大值):

result = bi[:, :8]
array([[1, 1, 1, 1, 1, 1, 1, 1],
       [0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 1]], dtype=uint8)

编辑:

这对于像答案中的小数字一样有效。如果需要8位以上,则应读取bi的前8个元素,然后读取第16至8个元素。有点混乱。

对于更通用的解决方案,最好翻转数组view。并且在拆包前裁剪会为您带来一些性能改进:

def int_to_bin(arr, n_bytes=1):       
    # arr is 1-D
    arr_ = np.fliplr(arr[:, None].view(np.uint8))[:, -n_bytes:]        
    return np.unpackbits(arr_, axis=1)

如果只想要4位,则可以进一步裁剪输出。 arr中的一百万int32大约需要10毫秒。

答案 1 :(得分:0)

这是我目前拥有的一种基于循环的显式解决方案,非常希望获得矢量化解决方案。

def int_to_bin_matrix(arr: np.ndarray, width: int):
  """Return the binary representation of matrix of integer array."""
  return np.array([[int(c) for c in np.binary_repr(i, width=width)] for i in arr], dtype=np.int32)

print(int_to_bin_matrix(np.arange(-2,2), 4))

[[1 1 1 0]
 [1 1 1 1]
 [0 0 0 0]
 [0 0 0 1]]