Encontrar máximos/mínimos locales con Numpy en una matriz numpy 1D
¿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.
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.signal
también proporciona argrelmax
y argrelmin
para encontrar máximos y mínimos respectivamente.
Si está buscando todas las entradas en la matriz 1d a
má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.
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 height
argumento, 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()
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()