2014-03-06 1 views
4

나는 0..2**m - 1 범위의 정수를 가지고 있으며 길이가 m 인 이진 numpy 배열로 변환하고 싶습니다. 예를 들어 m = 4이라고 말하면 이제 15 = 1111은 2 진수이므로 출력은 (1,1,1,1)이어야합니다. 2 = 10 이진이므로 출력은 (0,0,1,0이어야합니다. m3 인 경우 2(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) 

는 내가 코드에서이 어떤 m 근무 방법을 싶습니다.

+0

가'배열의 숫자에서 추론, 또는 인수로 지정할 수 m' 하는가? – amaurea

+0

@amaurea 인수로 지정됩니다. – felix

답변

8

당신은 단지 다음 적절한 비트 가중치를 얻고

>>> 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]]) 

처럼 뭔가를이 벡터화 할 수 있어야한다는 비트와 소요 :

>>> (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]]) 

은 여러가지 방법이 있습니다를, .astype(bool).astype(int) 등의 값을 1로 변환하려면 기본적으로 무작위로 선택했습니다.

0

여기에는 다소 '해킹 된'해결책이 있습니다.

def bin_array(num, m): 
    """Returns an array representing the binary representation of num in m bits.""" 
    bytes = int(math.ceil(m/8.0)) 
    num_arr = np.arange(num, num+1, dtype='>i%d' %(bytes)) 
    return np.unpackbits(num_arr.view(np.uint8))[-1*m:]  
+0

고맙습니다.하지만 m을 지정하고 적절하게 패드 할 수 있기를 원합니다. – felix

0

결과 배열을 수정할 수있는 것처럼 보입니다. 함수를 정확히 모르지만 np.unpackbits과 같은 대부분의 구현은 본질적으로 숫자의 크기를 알지 못합니다. 파이썬 int는 임의적으로 커질 수 있으며 네이티브 크기가 없습니다.

그러나 m을 알면 쉽게 배열을 수정할 수 있습니다. 기본적으로, 언팩 (unpack) 함수는 숫자에서 1이 가장 높은 바이트에 대해 몇 가지 비트 (즉, 8의 배수)를 제공합니다.

m = 4 
mval = np.unpackbits(np.uint8(15)) 

if len(mval) > m: 
    mval = mval[m-len(mval):] 
elif m > len(mval): 
    # Create an extra array, and extend it 
    mval = numpy.concatenate([numpy.array([0]*(m-len(mval)), dtype=uint8), mval]) 
+0

고맙습니다. 예 m은 인수로 지정됩니다. – felix

2

한 줄 버전, 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) 

예 :

당신은 다만 적당한 거리를 얻기 위해, 추가로 0 또는 앞에 추가 0을 제거해야
In [1]: bin_array(15, 6) 
Out[1]: array([0, 0, 1, 1, 1, 1], dtype=int8) 
한 번에하는 int 전체 NumPy와 배열을 확장하기위한

벡터화 버전 :

,493,210

예 :

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) 
관련 문제