How to detect dips with pandas or numpy array when data has repetitions?

Viewed 85

I'm trying to find the position of dips and bumps in an array by checking that n < n-1 and n > n+1.

It is a valid approach, but it fails when data repeats before bouncing, e.g. {100,80,80,100}.

See this example:

import numpy as np
import pandas as pd

data = np.array([100,250,200,350,650,650,650,500,400,300,300,350,100])

dips = np.flatnonzero((np.roll(data,1) > data).astype(int) & (data < np.roll(data,-1)).astype(int))
bumps = np.flatnonzero((np.roll(data,1) < data).astype(int) & (data > np.roll(data,-1)).astype(int))

print(dips,bumps)

I could make it work by removing the repetitive elements, so we get more output:

df = pd.DataFrame({'close':data})
data = (df.loc[df.shift(-1)['close'] != df['close']]).to_numpy()

dips = np.flatnonzero((np.roll(data,1) > data).astype(int) & (data < np.roll(data,-1)).astype(int))
bumps = np.flatnonzero((np.roll(data,1) < data).astype(int) & (data > np.roll(data,-1)).astype(int))

print(dips,bumps)

However, clearly in this case the order will not be preserved, hence the result is invalid.

I don't know it seems like an easy problem but I can't quite solve it yet without falling back to i, j loops.

Edit: the expected output should capture all dips and bumps in a correct order:

dips:  [2,9] or [2,10]
bumps: [1,4,11] or [1,5,11] or [1,6,11]

Since values are same in there we could use first, middle or last position.

enter image description here

1 Answers

I got it:

from scipy.signal import find_peaks
dips, bumps = find_peaks(-data), find_peaks(data)
Related