1

I am looking for a more efficient way to do the equivalent of

myarray * (2**arange(len(myarray))

Essentially I am after something like numpy.packbits that packs the bits into a single integer for any reasonable sized myarray yielding an appropriate size integer. I can implement this using numpy.packbits but I was wandering there is already a builtin that does this.

1
  • What do you mean by "builtin"? What is wrong with using numpy.packbits? Commented Jan 31, 2016 at 15:15

1 Answer 1

2

Three versions:

from numpy import *
from numba import jit

myarray=random.randint(0,2,64).astype(uint64) 

def convert1(arr) : return (arr*(2**arange(arr.size,dtype=uint64))).sum()

pow2=2**arange(64,dtype=uint64)
def convert2(arr) : return (arr*pow2[:arr.size]).sum()

@jit("uint64(uint64[:])")
def convert3(arr):
    m=1
    y=0
    for i in range(arr.size):
        y=y + pow2[i] * arr[i]
    return y

with times:

In [44]: %timeit convert1(myarray)
10000 loops, best of 3: 62.7 µs per loop

In [45]: %timeit convert2(myarray)
10000 loops, best of 3: 11.6 µs per loop

In [46]: %timeit convert3(myarray)
1000000 loops, best of 3: 1.55 µs per loop

Precomputing and Numba allow big improvements.

Sign up to request clarification or add additional context in comments.

1 Comment

The Numba solution is pretty much what ended up going with. I used bitwise operations in the loop instead of arithmetic. There is no significant speed difference between the two.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.