Although Joe Kington's answer is certainly correct (and quite flexible), it is more helpful than necessary. For someone trying to learn Numpy, I think a more direct way might be easier to understand.
As I noted on your question (and as Joe remarked), there seems to be an inconsistency between your description of the code's behavior and your example. Like Joe, I'm also going to suggest that you are describing the right behavior.
A few notes:
- Numpy works well with filters to indicate which elements to apply the operation to. I use them several times.
- The
np.flatnonzero function returns an array of indices defining locations at which the given array is non-zero (or True).
The code uses the example arrays that you provided.
import numpy as np TIME = np.array([0., 10., 20., 30., 40., 50., 60., 70., 80., 90.]) FLOW = np.array([100., 75., 60., 20.0, 60.0, 50.0, 20.0, 30.0, 20.0, 10.0]) TEMP = np.array([300., 310., 305., 300., 310., 305., 310., 305., 300., 295.0]) last_high_flow_index = np.flatnonzero(FLOW > 50)[-1] low_flow_indices = np.flatnonzero(FLOW < 30) acceptable_low_flow_indices = low_flow_indices[low_flow_indices > last_high_flow_index] apply_after_index = acceptable_low_flow_indices[0]
Now we have an index, after which the function should be applied to TEMP. If I read your question correctly, you would like the temperature to begin to decompose after your condition is satisfied. This can be done as follows:
time_delta = TIME[apply_after_index:] - TIME[apply_after_index] TEMP[apply_after_index:] = TEMP[apply_after_index:] * np.exp(-0.05 * time_delta)
TEMP updated, so print TEMP prints
[ 300. 310. 305. 300. 310. 305. 310. 184.99185121 110.36383235 65.82339724]
Alternatively, you can apply an arbitrary Python function to the corresponding elements, first vectorize the function:
def myfunc(x): ''' a normal python function that acts on individual numbers''' return x + 3 myfunc_v = np.vectorize(myfunc)
and then update the TEMP array:
TEMP[apply_after:] = myfunc_v(TEMP[apply_after:])