简体   繁体   中英

A way to get the local minima and maxima of a vector

I've been trying to retrieve the extrema of a vector that looks like this :

[![First case][1]][1]
(source: noelshack.com )

or like this : [![Second case][2]][2]
(source: noelshack.com )

I've been trying to retrieve local maxima and minima, it works well with : (diff(sign(diff(values_right_vector))) > 0).nonzero()[0] + 1 but afterwards it is only workaround and workaround because there is always a case where my previous workaround fails..

It has always this same pattern.

Do you have any ideas how can I retrieve those maxima and minima no matter the input vector ( left and right ) on the image.

Here is a sample :

[-2.7, -2.5, -2.1, -2.1, -1.8, -1.4, -0.9, -0.2, 0.5, 1.4, 2.2, 2.9, 3.5, 3.8, 3.8, 3.3, 2.3, 1.1, -0.5, -2.1, -3.5, -4.7, -5.5, -5.8, -5.6, -5.0, -4.2, -3.3, -2.3, -1.4, -0.8, -0.3, 0.0, 0.2, 0.2, 0.2, 0.1, 0.0, 0.0, 0.0, -0.1, -0.1, -0.1, -0.1, -0.1, -0.1, -0.2, -0.2, -0.2, -0.2, -0.2, -0.2, -0.2, -0.1, -0.1, -0.1, -0.1, -0.1, -0.2, -0.3, -0.4, -0.4, -0.5, -0.4, -0.3, -0.1, 0.2, 0.5, 0.7, 0.9, 0.9, 1.0, 0.9, 0.9, 0.9, 0.8, 0.7, 0.6, 0.3, 0.0, -0.4, -0.9, -1.3, -1.5, -1.6, -1.5, -1.1, -0.5, 0.2, 1.2, 2.1, 3.0, 3.8, 4.3, 4.3, 4.0, 3.2, 1.9, 0.4, -1.3, -3.0, -4.4, -5.4, -6.0, -6.0, -5.6, -4.8, -3.9, -2.9, -1.9, -1.2, -0.6, -0.2, 0.0, 0.1, 0.1, 0.1, 0.0, 0.0, -0.1, -0.1, -0.1, -0.1, 0.0, 0.0, 0.0, 0.0, 0.0, -0.1, -0.1, -0.1, -0.2, -0.2, -0.2, -0.2, -0.1, -0.1, 0.0, 0.0, 0.0, 0.0, -0.1, -0.3, -0.5, -0.7, -0.9, -1.1, -1.1, -1.0, -0.8, -0.4, 0.3, 1.1, 1.9, 2.8, 3.6, 4.2, 4.5, 4.5, 4.1, 3.4, 2.5, 1.5, 0.5, -0.5, -1.4, -2.1, -2.8, -3.3, -3.7, -3.9, -3.9, -3.8, -3.4, -2.9, -2.2, -1.3, -0.4, 0.7, 1.7, 2.5, 3.2, 3.6, 3.6, 3.2, 2.4, 1.3, -0.1, -1.6, -3.0, -4.1, -4.9, -5.1, -5.0, -4.4, -3.6, -2.7, -1.8, -1.1, -0.5, -0.1, 0.1, 0.2, 0.2, 0.1, 0.1, 0.0, -0.1, -0.1]```

 [1]: https://i.stack.imgur.com/O3er1.png
 [2]: https://i.stack.imgur.com/cbqNK.png

Scipy has a find_peaks function that you can manipulate to find the peaks you want using the distance parameter. The distance parameter tells Scipy how many spaces between samples it should look for peaks. You can adjust this to fit your data best. Using just the sample data you provided,

import numpy as np
from scipy.signal import find_peaks
import matplotlib.pyplot as plt

y = np.array([-2.7, -2.5, -2.1, -2.1, -1.8, -1.4, -0.9, -0.2, 0.5, 1.4, 2.2, 2.9, 3.5, 3.8, 3.8, 3.3, 2.3, 1.1, -0.5, -2.1, -3.5, -4.7, -5.5, -5.8, -5.6, -5.0, -4.2, -3.3, -2.3, -1.4, -0.8, -0.3, 0.0, 0.2, 0.2, 0.2, 0.1, 0.0, 0.0, 0.0, -0.1, -0.1, -0.1, -0.1, -0.1, -0.1, -0.2, -0.2, -0.2, -0.2, -0.2, -0.2, -0.2, -0.1, -0.1, -0.1, -0.1, -0.1, -0.2, -0.3, -0.4, -0.4, -0.5, -0.4, -0.3, -0.1, 0.2, 0.5, 0.7, 0.9, 0.9, 1.0, 0.9, 0.9, 0.9, 0.8, 0.7, 0.6, 0.3, 0.0, -0.4, -0.9, -1.3, -1.5, -1.6, -1.5, -1.1, -0.5, 0.2, 1.2, 2.1, 3.0, 3.8, 4.3, 4.3, 4.0, 3.2, 1.9, 0.4, -1.3, -3.0, -4.4, -5.4, -6.0, -6.0, -5.6, -4.8, -3.9, -2.9, -1.9, -1.2, -0.6, -0.2, 0.0, 0.1, 0.1, 0.1, 0.0, 0.0, -0.1, -0.1, -0.1, -0.1, 0.0, 0.0, 0.0, 0.0, 0.0, -0.1, -0.1, -0.1, -0.2, -0.2, -0.2, -0.2, -0.1, -0.1, 0.0, 0.0, 0.0, 0.0, -0.1, -0.3, -0.5, -0.7, -0.9, -1.1, -1.1, -1.0, -0.8, -0.4, 0.3, 1.1, 1.9, 2.8, 3.6, 4.2, 4.5, 4.5, 4.1, 3.4, 2.5, 1.5, 0.5, -0.5, -1.4, -2.1, -2.8, -3.3, -3.7, -3.9, -3.9, -3.8, -3.4, -2.9, -2.2, -1.3, -0.4, 0.7, 1.7, 2.5, 3.2, 3.6, 3.6, 3.2, 2.4, 1.3, -0.1, -1.6, -3.0, -4.1, -4.9, -5.1, -5.0, -4.4, -3.6, -2.7, -1.8, -1.1, -0.5, -0.1, 0.1, 0.2, 0.2, 0.1, 0.1, 0.0, -0.1, -0.1])

# Get the maxima and minima
maxima, _ = find_peaks(y, distance = 50)
minima, _ = find_peaks(-y, distance = 50)

find_peaks returns the indices of the peaks, which is why we can use -y to get the minima.

You can also index the maxima and minima to select the peaks you want, by doing something like maxima[::2] to select every other maxima.

fig, ax = plt.subplots()

ax.plot(y)
ax.plot(maxima, y[maxima], 'x')
ax.plot(minima, y[minima], 'x')
plt.show()

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM