Encontrar máximos/mínimos locales con Numpy en una matriz numpy 1D

Resuelto Navi asked hace 13 años • 13 respuestas

¿Puede sugerir una función de módulo de numpy/scipy que pueda encontrar máximos/mínimos locales en una matriz numpy 1D? Obviamente, el enfoque más simple es echar un vistazo a los vecinos más cercanos, pero me gustaría tener una solución aceptada que sea parte de la distribución numpy.

Navi avatar Jan 07 '11 18:01 Navi
Aceptado

En cienciaPy >= 0,11

import numpy as np
from scipy.signal import argrelextrema

x = np.random.random(12)

# for local maxima
argrelextrema(x, np.greater)

# for local minima
argrelextrema(x, np.less)

produce

>>> x
array([ 0.56660112,  0.76309473,  0.69597908,  0.38260156,  0.24346445,
    0.56021785,  0.24109326,  0.41884061,  0.35461957,  0.54398472,
    0.59572658,  0.92377974])
>>> argrelextrema(x, np.greater)
(array([1, 5, 7]),)
>>> argrelextrema(x, np.less)
(array([4, 6, 8]),)

Tenga en cuenta que estos son los índices de x que son máximo/mínimo local. Para obtener los valores, intente:

>>> x[argrelextrema(x, np.greater)[0]]

scipy.signaltambién proporciona argrelmaxy argrelminpara encontrar máximos y mínimos respectivamente.

danodonovan avatar Nov 21 '2012 11:11 danodonovan

Si está buscando todas las entradas en la matriz 1d amás pequeñas que sus vecinas, puede intentar

numpy.r_[True, a[1:] < a[:-1]] & numpy.r_[a[:-1] < a[1:], True]

También puedes suavizar tu matriz antes de este paso usando numpy.convolve().

No creo que haya una función dedicada para esto.

Sven Marnach avatar Jan 07 '2011 11:01 Sven Marnach

A partir de la versión 1.1 de SciPy, también puedes usar find_peaks . A continuación se muestran dos ejemplos tomados de la propia documentación.

Usando el heightargumento, se pueden seleccionar todos los máximos por encima de un cierto umbral (en este ejemplo, todos los máximos no negativos; esto puede ser muy útil si uno tiene que lidiar con una línea de base ruidosa; si desea encontrar mínimos, simplemente multiplique su entrada por -1):

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

x = electrocardiogram()[2000:4000]
peaks, _ = find_peaks(x, height=0)
plt.plot(x)
plt.plot(peaks, x[peaks], "x")
plt.plot(np.zeros_like(x), "--", color="gray")
plt.show()

ingrese la descripción de la imagen aquí

Otro argumento de gran ayuda es distance, que define la distancia mínima entre dos picos:

peaks, _ = find_peaks(x, distance=150)
# difference between peaks is >= 150
print(np.diff(peaks))
# prints [186 180 177 171 177 169 167 164 158 162 172]

plt.plot(x)
plt.plot(peaks, x[peaks], "x")
plt.show()

ingrese la descripción de la imagen aquí

Cleb avatar Nov 21 '2018 21:11 Cleb