使用合适的填充将整数转换为二进制数组

fel*_*lix 10 python numpy

我在范围内有整数,0..2**m - 1我想将它们转换为长度为二进制的numpy数组m.例如,说m = 4.现在15 = 1111是二进制的,所以输出应该是(1,1,1,1). 2 = 10在二进制中,所以输出应该是(0,0,1,0).如果m32应该转换(0,1,0).

我试过np.unpackbits(np.uint8(num))但是没有给出正确长度的数组.例如,

np.unpackbits(np.uint8(15))
Out[5]: array([0, 0, 0, 0, 1, 1, 1, 1], dtype=uint8)
Run Code Online (Sandbox Code Playgroud)

我想要一个适用于m我在代码中的任何方法的方法.

DSM*_*DSM 12

你应该能够对此进行矢量化,例如

>>> d = np.array([1,2,3,4,5])
>>> m = 8
>>> (((d[:,None] & (1 << np.arange(m)))) > 0).astype(int)
array([[1, 0, 0, 0, 0, 0, 0, 0],
       [0, 1, 0, 0, 0, 0, 0, 0],
       [1, 1, 0, 0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 0, 0, 0],
       [1, 0, 1, 0, 0, 0, 0, 0]])
Run Code Online (Sandbox Code Playgroud)

只获取适当的位权重,然后按位进行:

>>> (1 << np.arange(m))
array([  1,   2,   4,   8,  16,  32,  64, 128])
>>> d[:,None] & (1 << np.arange(m))
array([[1, 0, 0, 0, 0, 0, 0, 0],
       [0, 2, 0, 0, 0, 0, 0, 0],
       [1, 2, 0, 0, 0, 0, 0, 0],
       [0, 0, 4, 0, 0, 0, 0, 0],
       [1, 0, 4, 0, 0, 0, 0, 0]])
Run Code Online (Sandbox Code Playgroud)

有很多方法将其转换为1秒无论它是非零的(> 0)*1,.astype(bool).astype(int)等我选择了一个基本上是随机的.

  • 这是相反的顺序。 (2认同)

Fre*_*iss 5

单行版本,利用了以下方面的快速路径numpy.binary_repr

def bin_array(num, m):
    """Convert a positive integer num into an m-bit bit vector"""
    return np.array(list(np.binary_repr(num).zfill(m))).astype(np.int8)
Run Code Online (Sandbox Code Playgroud)

例:

In [1]: bin_array(15, 6)
Out[1]: array([0, 0, 1, 1, 1, 1], dtype=int8)
Run Code Online (Sandbox Code Playgroud)

向量化版本,用于一次扩展整个numpy整数数组:

def vec_bin_array(arr, m):
    """
    Arguments: 
    arr: Numpy array of positive integers
    m: Number of bits of each integer to retain

    Returns a copy of arr with every element replaced with a bit vector.
    Bits encoded as int8's.
    """
    to_str_func = np.vectorize(lambda x: np.binary_repr(x).zfill(m))
    strs = to_str_func(arr)
    ret = np.zeros(list(arr.shape) + [m], dtype=np.int8)
    for bit_ix in range(0, m):
        fetch_bit_func = np.vectorize(lambda x: x[bit_ix] == '1')
        ret[...,bit_ix] = fetch_bit_func(strs).astype("int8")

    return ret 
Run Code Online (Sandbox Code Playgroud)

例:

In [1]: vec_bin_array(np.array([[100, 42], [2, 5]]), 8)

Out[1]: array([[[0, 1, 1, 0, 0, 1, 0, 0],
                [0, 0, 1, 0, 1, 0, 1, 0]],

               [[0, 0, 0, 0, 0, 0, 1, 0],
                [0, 0, 0, 0, 0, 1, 0, 1]]], dtype=int8)
Run Code Online (Sandbox Code Playgroud)