Search code examples
pythonarraysloopsiterationenumerate

How do I make an array of the indices where the previous value did not meet a condition?


I have two arrays (v_1 and v_2), and I have a function that takes these arrays, finds the indices where their values exceed a threshold, finds the previous and next values of the array, and returns a new array (v_1f and v_2f) containing the indices where the previous value did not meet the threshold.

However, for some reason the return statement is not giving me these arrays. Why is that? Also, should this function produce an array with the conditions that I want?

def findbursts(v_1,v_2):

  for index, obj in enumerate(v_1):
      if obj == thresh:
          v_1f=(obj).nonzero()[0]
          # TODO Bounds-checking
          previous = v_1f[index - 1]
          if previous == None:
              v_1ff = v_1f

  for index, obj in enumerate(v_2):
      if obj == thresh:
          v_2f=(obj).nonzero()[0]
          # TODO Bounds-checking
          previous = v_2f[index - 1]
          if previous == None:
              v_2ff = v_2f

  return [v_1ff, v_2ff]

Solution

    1. You probably want obj >= thresh, using == doesn't match your problem description.
    2. Why are you comparing the previous value to None? You need to check if it's < thresh
    3. Can you clarify what the nonzero() call is for?
    4. You're not actually creating arrays inside your loop. v_1ff and v_2ff are single values.
      One way to fix it would be creating lists beforehand (v_1ff = []) and then append the found value to the list when it matches the condition.
    5. v_1ff is actually the previous value, not the previous index -- which do you want?
    6. If you're performing the exact same operation on two lists, it'd be cleaner to make a function that does it for a single list and then just call it twice.

    You can probably do all this much more easily with a list comprehension:

    from itertools import izip
    
    def find_bursts(data, thresh):
        return [i for i, (val, next_val) in enumerate(izip(data[:-1], data[1:])) 
                if val < thresh and next_val >= thresh]
    

    Breakdown:

    • izip(data([:-1], data[1:]) iterates over your array as pairs of adjacent elements
    • enumerate attaches the indices
    • if val < thresh and next_val >= thresh is your filter condition