Search code examples
pythonarraysnumpymask

Mask an array by the index given from other array


I have the following arrays:

a = [10, 31, 30, 11, 17, 12, 22, 25, 85, 17, 21, 43]
b = [0, 1, 4, 6]

I want to mask a based on the index given by array b. That means getting:

c = [True, True, False, False, True, False, True, False, False, False, False, False]

Solution

  • In [524]: a=np.array([10, 31, 30, 11, 17, 12, 22, 25, 85, 17, 21, 43])
    In [525]: b=np.array([0, 1, 4, 6])
    

    To make a boolean c that is True at the b indices, just use:

    In [526]: c=np.zeros(a.shape, bool)
    In [527]: c[b]=True
    
    In [528]: c
    Out[528]: 
    array([ True,  True, False, False,  True, False,  True, False, False,
           False, False, False], dtype=bool)
    

    Then you can select the values of a with:

    In [529]: a[c]
    Out[529]: array([10, 31, 17, 22])
    

    but you could just as well select them with b:

    In [530]: a[b]
    Out[530]: array([10, 31, 17, 22])
    

    but c is better for removing those, a[~c]. np.delete(a,b) does the same thing.

    Other array methods of generating c are

    np.in1d(np.arange(a.shape[0]),b)
    np.any(np.arange(a.shape[0])==b[:,None],0)
    

    And since I was just discussing masked arrays in another question, I could do the same here:

    In [542]: np.ma.MaskedArray(a,c)
    Out[542]: 
    masked_array(data = [-- -- 30 11 -- 12 -- 25 85 17 21 43],
                 mask = [ True  True False False  True False  True False False False False False],
           fill_value = 999999)