Pregunta

Puedo escribir algo a mí mismo mediante la búsqueda de cruces por cero de la primera derivada o algo así, pero parece que una función común, lo suficiente para ser incluido en las bibliotecas estándar. Alguien sabe de uno?

Mi aplicación particular es una matriz 2D, pero por lo general se utiliza para encontrar picos en FFT, etc.

En concreto, en este tipo de problemas, hay múltiples picos fuertes, y luego un montón de "picos" más pequeños que simplemente son causadas por el ruido que debe ser ignorado. Estos son sólo ejemplos; no es mi datos reales:

picos 1-dimensionales:

 salida de la FFT con picos

picos de 2 dimensiones:

transformada de Radon de salida con el pico de un círculo

El algoritmo pico de investigación sería encontrar la ubicación de estos picos (no sólo sus valores), y lo ideal sería encontrar el verdadero pico entre muestras, no sólo el índice con valor máximo, probablemente usando interpolación cuadrática o algo así.

Por lo general sólo se preocupan por unos picos fuertes, por lo que habría ya sea ser elegidos porque están por encima de un cierto umbral, o porque son los primeros n cumbres de una lista ordenada, clasificados en orden de amplitud.

Como ya he dicho, sé cómo escribir algo como esto a mí mismo. Sólo estoy preguntando si hay una función de pre-existente o paquete que se sabe que funcionan bien.

Actualización:

traducido un script de MATLAB y funciona bastante bien para el caso 1-D, pero podría ser mejor .

Actualización Actualizado:

creado una versión mejor para el caso 1-D.

¿Fue útil?

Solución

No creo que lo que busca es proporcionada por SciPy. Me gustaría escribir el código de mí mismo, en esta situación.

La interpolación spline y suavizado de scipy.interpolate están bastante bien y podría ser muy útil para picos de ajuste y luego encontrar la ubicación de su máximo.

Otros consejos

Estoy buscando a un problema similar, y he encontrado algunas de las mejores referencias provienen de la química (de picos en la búsqueda de datos-espectrometría de masas). Para una buena revisión a fondo de un pico algoritmos para encontrar lea este . Esta es una de las mejores críticas más claros de técnicas hallazgo pico que he correr a través. (Wavelets son los mejores para la búsqueda de picos de este tipo de datos ruidosos.).

Parece que sus picos están claramente definidos y no se ocultan en el ruido. Siendo ese el caso, me gustaría recomendar el uso de derivados savtizky-Golay suaves para encontrar los picos (Si acaba de diferenciar los datos anteriores que tendrá un lío de falsos positivos.). Esta es una técnica muy eficaz y es bastante fácil de implementado (usted no necesita una clase de matriz w / operaciones básicas). Si simplemente encontrar el paso por cero de la primera derivada S-G Creo que serás feliz.

La función scipy.signal.find_peaks , como su nombre indica, es útil para esto. Pero es importante entender bien sus parámetros width, threshold, distance y, sobre todo prominence para obtener una buena extracción de pico.

Según mis pruebas y la documentación, el concepto de prominencia es "el concepto de utilidad" para mantener las buenas picos, y desechar los picos de ruido.

¿Cuál es (topográficos) prominencia ? Se "la altura mínima necesaria para descender para llegar desde la cumbre a cualquier terreno más alto" , como se puede ver aquí:

 introducir descripción de la imagen aquí

La idea es:

  

A mayor prominencia, la más "importante" es el pico.

Prueba:

 introducir descripción de la imagen aquí

He utilizado un (ruidoso) sinusoide de frecuencia variable a propósito porque muestra muchas dificultades. Podemos ver que el parámetro width no es muy útil aquí, porque si se establece un mínimo width demasiado alto, entonces no va a ser capaz de seguir muy cerca picos en la parte alta frecuencia. Si establece width demasiado bajo, que tendría muchos picos no deseados en la parte izquierda de la señal. El mismo problema con distance. threshold sólo compara con los vecinos directos, que no es útil aquí. prominence es el que da la mejor solución. Tenga en cuenta que puede combinar muchos de estos parámetros!

Código:

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

x = np.sin(2*np.pi*(2**np.linspace(2,10,1000))*np.arange(1000)/48000) + np.random.normal(0, 1, 1000) * 0.15
peaks, _ = find_peaks(x, distance=20)
peaks2, _ = find_peaks(x, prominence=1)      # BEST!
peaks3, _ = find_peaks(x, width=20)
peaks4, _ = find_peaks(x, threshold=0.4)     # Required vertical distance to its direct neighbouring samples, pretty useless
plt.subplot(2, 2, 1)
plt.plot(peaks, x[peaks], "xr"); plt.plot(x); plt.legend(['distance'])
plt.subplot(2, 2, 2)
plt.plot(peaks2, x[peaks2], "ob"); plt.plot(x); plt.legend(['prominence'])
plt.subplot(2, 2, 3)
plt.plot(peaks3, x[peaks3], "vg"); plt.plot(x); plt.legend(['width'])
plt.subplot(2, 2, 4)
plt.plot(peaks4, x[peaks4], "xk"); plt.plot(x); plt.legend(['threshold'])
plt.show()

Hay una función en scipy scipy.signal.find_peaks_cwt llamada que suena como es adecuado para sus necesidades, sin embargo, no tengo experiencia con él, así que no puedo recomendar ..

http://docs.scipy.org/ doc / scipy / referencia / generado / scipy.signal.find_peaks_cwt.html

Para los que no está seguro acerca de lo que el pico de búsqueda de algoritmos para usar en Python, aquí una visión rápida de las alternativas: https://github.com/MonsieurV/py-findpeaks

El deseo mismo un equivalente a la función findpeaks MatLab, he encontrado que la detect_peaks función de Marcos Duarte es un buen partido.

Muy fácil de usar:

import numpy as np
from vector import vector, plot_peaks
from libs import detect_peaks
print('Detect peaks with minimum height and distance filters.')
indexes = detect_peaks.detect_peaks(vector, mph=7, mpd=2)
print('Peaks are: %s' % (indexes))

¿Qué le dará:

 detect_peaks resultados

La detección de picos en un espectro de una manera fiable se ha estudiado un poco, por ejemplo, todo el trabajo en el modelado sinusoidal para señales de audio de música / en los años 80. Busque "Modelado sinusoidal" en la literatura.

Si las señales son tan limpias como el ejemplo, un simple "Dame algo con una amplitud mayor que N vecinos" debería funcionar razonablemente bien. Si usted tiene señales ruidosas, una forma sencilla pero eficaz es mirar sus picos en el tiempo, para hacer un seguimiento de ellos: a continuación, detectar líneas espectrales en lugar de picos espectrales. OIA, que calcule la FFT en una ventana deslizante de la señal, para obtener un conjunto de espectro en el tiempo (también llamada espectrograma). A continuación, observa la evolución del pico espectral en el tiempo (es decir, en las ventanas consecutivas).

Hay funciones y métodos para encontrar los valores extremos de los datos, que es probablemente lo que necesita en el primer caso estadísticos estándar. El uso de derivados resolvería el segundo. No estoy seguro de un método que soluciona estos dos funciones continuas y los datos muestreados, sin embargo.

Lo primero es lo primero, la definición de "pico" es vaga si sin más especificaciones. Por ejemplo, para la siguiente serie, le llame 5-4-5 un pico o dos?

1-2-1-2-1-1-5-4-5-1-1-5-1

En este caso, se necesitan al menos dos umbrales: 1) un alto umbral por encima del cual solamente puede un valor del registro de extremo como un pico; y 2) un umbral bajo de modo que los valores extremos separados por pequeños valores por debajo de ella se convertirá en dos picos.

La detección del pico es un tema bien estudiado en la literatura Teoría del Valor Extremo, también conocido como "desagrupación de valores extremos". Sus aplicaciones típicas incluyen la identificación de eventos de peligros basado en lecturas continuas de variables ambientales por ejemplo el análisis de la velocidad del viento para detectar eventos de tormenta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top