Search code examples
pythonnumpy

Generating binary arrays with alternating values based on change indices in NumPy


I have an array a of increasing indexes, e.g. [2 5 9 10], which indicates positions of value change. Assuming the output values are 0 and 1, I want to get array b:

[0 0 1 1 1 0 0 0 0 1 0]

Is there a NumPy magic to transform a into b?


Solution

  • One way among many others

    a=np.array([2,5,9,10])
    x=np.zeros((a.max()+1,), dtype=np.uint8)
    x[a]=1
    b=x.cumsum()%2
    

    Some explanation (but I guess code, in this rare case, is its own explanation, since it is quite easy, once you see it) x (after x[a]=1) contains 1 at each given position in a. So x.cumsum() contains a value that increments for each of those values: 0 for the 2 first, then 1 for 3 next then 2, then 3, then 4... So x.cumsum()%2 alternates between 1 and 0.

    Note that I use np.uint8 type because I am cheap, and I can't help thinking "why shoud I pay 32 bits when 8 are enough for a size 11 array". But in reality, since 256 is even, it wouldn't really matter even if a had billions of values. Just x.cumsum() would roll back from 255 to 0 because of overflow. And then x.cumsum()%2 would have the same value.