-1

I want to recover the periods that are in an array of sampled data:

signal = [45, 46, -12, -12.5, 32, 35, 34, 25, 23, -23, -65, -3, 43, 23]

I want to count the size of a period. A period starts with a positive number and moves to negative numbers and then returns to a positive number.

For example:

period1=[45 46 -12 -12.5 32]  # length=5
period2=[32 35 34 25 23 -23 -65 -3 43]  # length=8

How can this be done?

Stephen Rauch
  • 40,722
  • 30
  • 82
  • 105
Diao ibrahima
  • 51
  • 2
  • 9

1 Answers1

1

The trick here is to use numpy.diff() twice. The first diff can be used to find the sign crossings. The second diff can be used to find the distance between those crossing.

Code:

import numpy as np

# put the data into a numpy array
signal = np.array(
    [45, 46, -12, -12.5, 0, 32, 35, 34, 25, 23, -23, -65, -3, 43, 23])

# consider zeros to be negative, since we are looking for return to positive
signal[np.where(signal == 0.0)] = -1e-100

# find any returns to positive
return_to_positive = 1 + np.where(2 == np.diff(np.sign(signal)))[0]

# the periods are the distance between `return to positives`
periods = np.diff(return_to_positive)

Output:

>>> print(periods)
[8]

Magic Explained:

We first need to insure there are no zeros in out data. This is because we want to have clean zero crossings. Set any zeros to just less than zero, since we want the first positive value to be the start of period.

# consider zeros to be negative, since we are looking for return to positive
signal[np.where(signal == 0.0)] = -1e-100

Take the sign of the signal, and then diff it. Anywhere this is 2 is where the signal goes from negative to positive. Add 1 to the indices because the previous diff removed one element from the array. (Side note, pandas does this for you)

# find the indices for any returns to positive
return_to_positive = 1 + np.where(2 == np.diff(np.sign(signal)))[0]

Finally, take the distance between the indices for each zero crossing to get the periods.

# the periods are the distance between `return to positives`
periods = np.diff(return_to_positive)
Stephen Rauch
  • 40,722
  • 30
  • 82
  • 105