Pergunta

Eu posso escrever algo me por encontrar passagens por zero da primeira derivada ou algo assim, mas parece que uma função comum o suficiente para ser incluído nas bibliotecas padrão. Alguém sabe de um?

Meu aplicativo específico é uma matriz 2D, mas normalmente seria usado para encontrar picos em FFTs, etc.

Especificamente, esses tipos de problemas, existem vários picos fortes e muito depois de menores "picos" que são apenas provocados pelo ruído que deve ser ignorado. Estes são apenas exemplos; não o meu dados reais:

picos 1-dimensionais:

 saída FFT com picos

picos de 2 dimensões:

Radon transformar a saída com pico circundado

O algoritmo de apuramento pico iria encontrar a localização desses picos (não apenas seus valores) e, idealmente, iria encontrar o verdadeiro pico inter-amostra, e não apenas o índice com valor máximo, provavelmente usando quadrática interpolação ou algo assim.

Normalmente, você só se preocupam com alguns picos fortes, para que eles quer ser escolhido porque eles estão acima de um certo limiar, ou porque é a primeira n picos de uma lista ordenada, classificados por amplitude.

Como eu disse, eu sei como escrever algo como isso mesmo. Eu só estou perguntando se há uma função pré-existente ou pacote que é conhecido para trabalhar bem.

Update:

traduzido um script MATLAB e funciona decentemente para o caso 1-D, mas poderia ser melhor .

atualização Atualizado:

criou uma versão melhor para o caso 1-D.

Foi útil?

Solução

Eu não acho que o que você está procurando é fornecido pelo SciPy. Eu ia escrever o código de mim mesmo, nesta situação.

A interpolação spline e suavização de scipy.interpolate são bastante agradável e pode ser bastante útil na montagem picos e, em seguida, encontrar a localização do seu máximo.

Outras dicas

Eu estou olhando para um problema semelhante, e eu encontrei alguns dos melhores referências vêm de química (de picos encontrando em dados em massa-spec). Para uma boa revisão completa de peaking algoritmos constatação ler este . Este é um dos melhores comentários mais claros de técnicas constatação de pico que eu atravessam. (Wavelets são os melhores para encontrar picos desse tipo nos dados ruidosos.).

Parece que seus picos são claramente definidas e não estão escondidos no ruído. Sendo esse o caso, eu recomendo o uso de derivados savtizky-Golay suaves para encontrar os picos (Se você acabou de diferenciar os dados acima, você vai ter uma confusão de falsos positivos.). Esta é uma técnica muito eficaz e é muito fácil de implementar (você precisa de uma classe de matriz w / operações básicas). Se você simplesmente encontrar o cruzamento zero da primeira derivada S-G eu acho que você vai ser feliz.

A função scipy.signal.find_peaks , como seu nome sugere, é útil para este. Mas é importante entender bem seus parâmetros width, threshold, distance e acima de tudo prominence para obter uma extração bom pico.

De acordo com meus testes e a documentação, o conceito de destaque é "o conceito útil" para manter os bons picos, e descartar os picos ruidosos.

O que é (topográfico) proeminência ? É "a altura mínima necessária para descer para começar a partir da cúpula para qualquer terreno superior" , como pode ser visto aqui:

 enter descrição da imagem aqui

A idéia é:

Quanto maior o destaque, o mais "importante" o pico é.

Test:

 enter descrição da imagem aqui

Eu usei um (barulhento) sinusoid-frequência variável de propósito, porque mostra muitas dificuldades. Podemos ver que o parâmetro width não é muito útil aqui, porque se você definir um width mínimo muito alto, então não vai ser capaz de controlar picos muito próximos na parte alta frequência. Se você definir width muito baixo, você teria muitos picos indesejados na parte esquerda do sinal. Mesmo problema com distance. threshold só compara com os vizinhos directos, que não é útil aqui. prominence é aquele que dá a melhor solução. Note que você pode combinar muitos destes 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()

Há uma função em scipy scipy.signal.find_peaks_cwt chamada que soa como é adequado para suas necessidades, no entanto eu não tenho experiência com isso para que eu não posso recomendar ..

http://docs.scipy.org/ doc / scipy / reference / gerado / scipy.signal.find_peaks_cwt.html

Para aqueles que não tem certeza sobre o que de pico encontrar algoritmos para uso em Python, aqui uma visão rápida das alternativas: https://github.com/MonsieurV/py-findpeaks

Querendo me um equivalente para a função findpeaks MatLab, eu descobri que o detect_peaks funcionar de Marcos Duarte é uma boa captura.

muito 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))

O que vai lhe dar:

 detect_peaks resultados

picos detectar em um espectro de uma forma confiável foi estudado um pouco, por exemplo, todo o trabalho na modelagem senoidal para sinais áudio / música nos anos 80. Procure por "sinusoidal Modeling" na literatura.

Se os seus sinais são tão limpos como o exemplo, um simples "me dê algo com uma amplitude maior do que vizinhos n" deve funcionar razoavelmente bem. Se você tem sinais ruidosos, um simples, mas eficaz maneira é olhar para os seus picos no tempo, para rastreá-los: você, então detectar linhas espectrais em vez de picos espectrais. IOW, você calcular a FFT em uma janela deslizante de seu sinal, para obter um conjunto de espectro no tempo (também chamado espectrograma). Você, então, olhar para a evolução do pico espectral no tempo (ou seja, em janelas consecutivas).

Existem funções e métodos para encontrar valores discrepantes de dados, que é provavelmente o que você precisa, no primeiro caso estatísticos padrão. A utilização de derivados iria resolver o seu segundo. Não tenho a certeza de um método que resolve as duas funções contínuas e dados amostrados, no entanto.

As primeiras coisas primeiro, a definição de "pico" é vaga se sem mais especificações. Por exemplo, para as seguintes séries, você chamaria 5-4-5 um pico ou dois?

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

Neste caso, você vai precisar de pelo menos dois limites: 1) um alto limiar apenas acima do qual pode um registo valor extremo como um pico; e 2) um limite baixo de modo que os valores extremos separados por pequenos valores abaixo torna-se dois picos.

detecção de pico é um assunto bem estudado na teoria de valores extremos literatura, também conhecido como "desagrupamento de valores extremos". Suas aplicações típicas incluem a identificação de eventos de risco com base em leituras contínuas de variáveis ??ambientais por exemplo analisando a velocidade do vento para detectar eventos de tempestade.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top