[Numpy-discussion] int to binary

josef.pktd@gmai... josef.pktd@gmai...
Mon Apr 29 12:00:54 CDT 2013


On Mon, Apr 29, 2013 at 12:24 PM, Warren Weckesser
<warren.weckesser@gmail.com> wrote:
> On 4/29/13, josef.pktd@gmail.com <josef.pktd@gmail.com> wrote:
>>  Is there a available function to convert an int to binary
>> representation as sequence of 0 and 1?
>>
>>
>>  binary_repr produces strings and is not vectorized
>>
>>>>> np.binary_repr(5)
>> '101'
>>>>> np.binary_repr(5, width=4)
>> '0101'
>>>>> np.binary_repr(np.arange(5), width=4)
>> Traceback (most recent call last):
>>   File "<stdin>", line 1, in <module>
>>   File "C:\Python26\lib\site-packages\numpy\core\numeric.py", line
>> 1732, in binary_repr
>>     if num < 0:
>> ValueError: The truth value of an array with more than one element is
>> ambiguous. Use a.any() or a.all()
>>
>> ------------
>> That's the best I could come up with in a few minutes:
>>
>>
>>>>> k = 3;  int2bin(np.arange(2**k), k, roll=False)
>> array([[ 0.,  0.,  0.],
>>        [ 1.,  0.,  0.],
>>        [ 0.,  0.,  1.],
>>        [ 1.,  0.,  1.],
>>        [ 0.,  1.,  0.],
>>        [ 1.,  1.,  0.],
>>        [ 0.,  1.,  1.],
>>        [ 1.,  1.,  1.]])
>>>>> k = 3;  int2bin(np.arange(2**k), k, roll=True)
>> array([[ 0.,  0.,  0.],
>>        [ 0.,  0.,  1.],
>>        [ 0.,  1.,  0.],
>>        [ 0.,  1.,  1.],
>>        [ 1.,  0.,  0.],
>>        [ 1.,  0.,  1.],
>>        [ 1.,  1.,  0.],
>>        [ 1.,  1.,  1.]])
>>
>> -----------
>> def int2bin(x, width, roll=True):
>>     x = np.atleast_1d(x)
>>     res = np.zeros(x.shape + (width,) )
>>     for i in range(width):
>>         x, r = divmod(x, 2)
>>         res[..., -i] = r
>>     if roll:
>>         res = np.roll(res, width-1, axis=-1)
>>     return res
>>
>
> Here one way, in which each value is and'ed (with broadcasting) with
> an array of values with a 1 in each consecutive bit.  The comparison `
> != 0` converts the values from powers of 2 to bools, and then
> `astype(int)` converts those to 0s and 1s.  You'll probably want to
> adjust how reshaping is done to get the result the way you want it.
>
> In [1]: x = array([0, 1, 2, 3, 15, 16])
>
> In [2]: width = 5
>
> In [3]: ((x.reshape(-1,1) & (2**arange(width))) != 0).astype(int)
> Out[3]:
> array([[0, 0, 0, 0, 0],
>        [1, 0, 0, 0, 0],
>        [0, 1, 0, 0, 0],
>        [1, 1, 0, 0, 0],
>        [1, 1, 1, 1, 0],
>        [0, 0, 0, 0, 1]])

nice and tricky.
I've never seen the bitwise_and in action like this. Maybe something
to remember.

--------
example
indexing into a 2x2x2 contingency table
>>> k = 3
>>> a3 = int2bin(np.arange(2**k), k)
>>> c3 = np.arange(2**k).reshape(*([2]*k))
>>> c3[tuple(a3.T)]
array([0, 1, 2, 3, 4, 5, 6, 7])

but I need to flatten 2 of those into a 2*2*2 x 2*2*2 table  (2**(2k) table)

Thanks,

Josef


>
>
> Warren
>
>
>>
>> Josef
>> _______________________________________________
>> NumPy-Discussion mailing list
>> NumPy-Discussion@scipy.org
>> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>>
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion@scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion


More information about the NumPy-Discussion mailing list