0

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

1 Answer 1

1
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
 
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you it works I tried to do the opposite where instead of a drawdown of 100 looked for an upside of 100. But it is not really working I tried the following code: row_mins = np.triu( arr[None, : ] + arr[ :, None ] ).min(axis = 1 ) return np.count_nonzero(row_mins >= limit )
I'm not exactly sure what you 're trying to do but I think you still want differences, not the sum and probably need max, not min. So row_maxs = np.triu( arr[None, : ] - arr[ :, None ] ).max(axis = 1 ). Does that work?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.