MHankin
MHankin

Reputation: 176

First element of series to cross threshold in numpy, with handling of series that never cross

I have a numpy array of N time series of length T. I want the index at which each first crosses some threshold, and a -1 or something similar if it never crosses. Take ts_array = np.randn(N, T)

np.argmax(ts_array > cutoff, axis=1) gets close, but it returns a 0 for both time series that cross the threshold at time 0, and time series that never cross.

np.where(...) and np.nonzero(...) are possibilities, but their return values would require rather gruesome handling to extract the vector in which I'm interested

This question is similar to Numpy first occurence of value greater than existing value but none of the answers there solve it.

Upvotes: 2

Views: 2943

Answers (2)

piRSquared
piRSquared

Reputation: 294508

One liner:

(ts > c).argmax() if (ts > c).any() else -1

assuming ts = ts_array and c = cutoff

Otherwise:

Use argmax() and any()

np.random.seed([3,1415])

def xover(ts, cut):
    x = ts > cut
    return x.argmax() if x.any() else -1

ts_array = np.random.random(5).round(4)

ts_array looks like:

print ts_array, '\n'

[ 0.4449  0.4076  0.4601  0.4652  0.4627] 

Various checks:

print xover(ts_array, 0.400), '\n'

0 

print xover(ts_array, 0.460), '\n'

2 

print xover(ts_array, 0.465), '\n'

3 

print xover(ts_array, 1.000), '\n'

-1 

Upvotes: 7

grey_ranger
grey_ranger

Reputation: 1030

It's not too bad with np.where. I would use the following as a starting point:

ts_array = np.random.rand(10, 10)
cutoff = 0.5

# Get a list of all indices that satisfy the condition
rows, cols = np.where(ts_array > cutoff)
if len(rows) > 0:
    index = (rows[0], cols[0])
else:
    index = -1

Note that np.where returns two arrays, a list of row indices and a list of column indices. They are matched, so choosing the first one of each array will give us the first instance where the values are above the cutoff. I don't have a nice one-liner, but the handling code isn't too bad. It should be easily adaptable to your situation.

Upvotes: 1

Related Questions