Search code examples
pythonarraysnumpyvectorization

numpy vectorized way to count non-zero bits in array of integers


I have an array of integers:

[int1, int2, ..., intn]

I want to count how many non-zero bits are in the binary representation of these integers.

For example:

bin(123) -> 0b1111011, there are 6 non-zero bits

Of course I can loop over list of integers, use bin() and count('1') functions, but I'm looking for vectorized way to do it.


Solution

  • Assuming your array is a, you can simply do:

    np.unpackbits(a.view('uint8')).sum()
    

    example:

    a = np.array([123, 44], dtype=np.uint8)
    #bin(a) is [0b1111011, 0b101100]
    np.unpackbits(a.view('uint8')).sum()
    #9
    

    Comparison using benchit:

    #@Ehsan's solution
    def m1(a):
      return np.unpackbits(a.view('uint8')).sum()
    
    #@Valdi_Bo's solution
    def m2(a):
      return sum([ bin(n).count('1') for n in a ])
    
    in_ = [np.random.randint(100000,size=(n)) for n in [10,100,1000,10000,100000]]
    

    m1 is significantly faster.

    enter image description here