pythonarraysnumpy

How to quickly find the minimum element to the right for every element of a Numpy array?


Let's say I have an array:

a = [1,4,3,6,4]

I want to get an array where for every element I have the smallest value in a to the right (inclusive). That is, for a, I would want to create an array:

[1,3,3,4,4]

Is there a quick, concise way to do this?


Solution

  • You question is actually ambiguous. Do you want to consider the following value or all following values?

    considering all following values

    compute a cumulated minimum on the reversed array with minimum.accumulate:

    a = np.array([1,4,3,6,4])
    
    out = np.minimum.accumulate(a[::-1])[::-1]
    

    Output:

    array([1, 3, 3, 4, 4])
    

    With pure python and itertools.accumulate:

    from itertools import accumulate
    
    a = [1,4,3,6,4]
    
    out = list(accumulate(a[::-1], min))[::-1]
    # [1, 3, 3, 4, 4]
    

    considering only the next value

    You could shift the values and use np.minimum:

    a = np.array([1,4,3,6,4])
    
    out = np.minimum(a, np.r_[a[1:], a[-1]])
    

    Output:

    array([1, 3, 3, 4, 4])
    

    or compare the successive values and build a mask to modify a in place:

    a = np.array([1,4,3,6,4])
    
    m = a[:-1] > a[1:]
    # or
    # m = np.diff(a) < 0
    
    a[np.r_[m, False]] = a[1:][m]
    

    Modified a:

    array([1, 3, 3, 4, 4])
    

    difference

    a = np.array([1,4,3,6,5,6,4])
    
    np.minimum.accumulate(a[::-1])[::-1]
    # array([1, 3, 3, 4, 4, 4, 4])
    
    np.minimum(a, np.r_[a[1:], a[-1]])
    # array([1, 3, 3, 5, 5, 4, 4])