我在0..2**m - 1
范围内有整数,我想将它们转换为长度为m
的二进制numpy数组。例如,说m = 4
。现在15 = 1111
为二进制,因此输出应为(1,1,1,1)
。二进制2 = 10
,因此输出应为(0,0,1,0
)。如果m
为3
,则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 :(得分:11)
您应该能够对此进行矢量化,例如
>>> 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]])
有很多方法可以将它转换为1,无论它是非零(> 0)*1
,.astype(bool).astype(int)
等等。我基本上随机选择了一个。
答案 1 :(得分:0)
这是一个有点'hacky'的解决方案。
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:]
答案 2 :(得分:0)
好像你可以修改生成的数组。我不完全知道这个函数,但像np.unpackbits
这样的大多数实现本身并不知道数字的大小 - 毕竟python int可以任意大,并且没有原生大小。
但是,如果您知道m
,则可以轻松“修复”数组。基本上,解包函数将为数字中具有最高1的字节提供一些位数(即8的倍数)。您只需要删除额外的0或前置0,以获得正确的距离:
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])