Search code examples
arrayspython-3.xnumpycomparesubtraction

Comparing values in an array and calculating the difference in ranges Numpy Python


I am trying to code a function that checks if a value has went down more than 100 between a range of values for val 103.0, 58.8, 35, -47 the values went from 103 to -47 which is -150 also 58.8, 35, -47 the values went from 58 to -47 that is a decrease of -105. So those are 2 of the cases were there was a drop from an initial value to a value equivalent to or over -100. It checks if there was a drop by -100 for each value in the array till the end of the array. So if it took the number 7.4 then it would check for the rest of the array being 1180.9, 0.6, 103.0, 58.8, 35, -47, 47.2, 78.1, 37.8 and if the value is 1180.9 then it would check the values 0.6, 103.0, 58.8, 35, -47, 47.2, 78.1, 37.8. how would I be able to do that with numpy.

import numpy as np 

val = np.array([7.4, 1180.9, 0.6, 103.0, 58.8, 35, -47, 47.2, 78.1, 37.8])
val2 = np.array([46.5, 55.7, 7.0, 19.6, 7.6, 36.5, 34.7, 101.9, 179.7, 85.5])
val3 = np.array([120, 20, -80, -5.5])

differences = 100

def run(values):
    minimums = np.subtract.accumulate(values)
    print(f'Number it has been below or equal to {differences} is {values}')
    return minimums
    
print(run(val))
print(run(val2))
print(run(val3))

Expected Output:

Number it has been below or equal to -100 is 3
Number it has been below or equal to -100 is 0
Number it has been below or equal to -100 is 2

Solution

  • import numpy as np
    
    val = np.array([7.4, 1180.9, 0.6, 103.0, 58.8, 35, -47, 47.2, 78.1, 37.8]) 
    val2 = np.array([46.5, 55.7, 7.0, 19.6, 7.6, 36.5, 34.7, 101.9, 179.7, 85.5]) 
    val3 = np.array([120, 20, -80, -5.5]) 
    
    def run( arr, limit ): 
        row_mins = np.triu( arr[None, : ] - arr[ :, None ] ).min(axis = 1 ) 
        return np.count_nonzero( row_mins <= -limit ) 
    

    Expanded:

    def run( arr, limit ):
        # Uncomment the print statements to see what is happening.
        temp = arr[None, : ] - arr[ :, None ]  # difference of each element all elements
        # print( temp )
        temp1 = np.triu( temp )  # Keep the upper triangle, set lower to zero
        # print( temp1 )
        row_mins = temp1.min( axis = 1 )   # Minimum for each row
        # print( row_mins )
        return np.count_nonzero( row_mins <= -limit ) # Count how many row_mins are <= limit
    

    Results:

    run(val, 100)   # 3
    run(val2, 100)  # 0
    run(val3, 100)  # 2