HOWTO · Python
Encontre picos em Python
Este tutorial demonstra os algoritmos de localização de pico em Python.
Nesta página
Um máximo local é uma amostra maior que as amostras próximas; ela não precisa ser o maior valor de toda a série. Para uma sequência unidimensional, compare cada valor interno com seus vizinhos para obter um resultado simples, ou use scipy.signal.find_peaks() quando precisar filtrar os candidatos. Essas funções retornam índices começando em zero, referentes aos dados originais; use esses índices para recuperar os valores dos picos.
Use NumPy para encontrar máximos locais simples
Este exemplo compacto usa um array unidimensional e mostra cada índice detectado junto com seu valor.
import numpy as np
data = np.array([1, 3, 7, 1, 2, 6, 0, 5, 0, 4])
local_maxima = (data[1:-1] > data[:-2]) & (data[1:-1] > data[2:])
indices = np.flatnonzero(local_maxima) + 1
print("indices:", indices.tolist())
print("values:", data[indices].tolist())
indices: [2, 5, 7]
values: [7, 6, 5]
As duas comparações exigem que uma amostra seja estritamente maior que os dois vizinhos imediatos. O fatiamento compara apenas as amostras internas, portanto o primeiro e o último elementos não são candidatos; platôs com valores iguais também são excluídos. O deslocamento do índice converte as posições do array menor de volta para as posições em data. Essa abordagem com NumPy é útil quando essa regra específica se aplica aos seus dados. Para esta entrada, os índices detectados são [2, 5, 7] e os valores correspondentes são [7, 6, 5].
Use scipy.signal.find_peaks() para filtrar picos
Para uma busca geral de picos em uma sequência unidimensional, scipy.signal.find_peaks(), do SciPy, retorna os índices dos máximos locais e permite aplicar condições opcionais. O exemplo a seguir seleciona picos com altura mínima de 3 e imprime seus índices e valores:
import numpy as np
from scipy.signal import find_peaks
data = np.array([1, 3, 7, 1, 2, 6, 0, 5, 0, 4])
indices, properties = find_peaks(data, height=3, distance=2, prominence=1)
print("indices:", indices.tolist())
print("values:", data[indices].tolist())
indices: [2, 5, 7]
values: [7, 6, 5]
height filtra pelo valor do pico, distance exige um espaçamento mínimo, em amostras, entre os picos mantidos, e prominence mede o quanto um pico se destaca em relação ao entorno. distance afeta quais picos são mantidos; não é retornado como propriedade. Outras condições opcionais incluem width e threshold. O SciPy retorna os índices e um dicionário de propriedades com as propriedades geradas para as condições aplicáveis solicitadas. Para esta entrada e estes argumentos, os índices retornados são [2, 5, 7], com valores [7, 6, 5]. Escolha condições que descrevam o sinal, em vez de presumir que todo máximo local seja relevante.
Use scipy.signal.argrelextrema() para encontrar extremos relativos
Use scipy.signal.argrelextrema() quando quiser comparar amostras em uma vizinhança definida. Passe um comparador, como np.greater, para encontrar máximos e defina order como o número de amostras de cada lado incluídas na comparação. O resultado é uma tupla de arrays de índices, um para cada dimensão da entrada; em um array unidimensional, acesse os índices com [0].
import numpy as np
from scipy.signal import argrelextrema
data = np.array([1, 3, 7, 1, 2, 6, 0, 5, 0, 4])
indices = argrelextrema(data, np.greater, order=1)[0]
print("indices:", indices.tolist())
print("values:", data[indices].tolist())
indices: [2, 5, 7]
values: [7, 6, 5]
Com order=1, cada candidato é comparado com uma amostra de cada lado. Um valor maior de order usa uma vizinhança mais ampla e pode retornar um conjunto diferente de extremos relativos. Para esta entrada com order=1, os índices retornados são [2, 5, 7] e seus valores são [7, 6, 5].
Use detecta.detect_peaks() como alternativa
detecta.detect_peaks() é uma alternativa de terceiros para sequências unidimensionais. Instale a dependência no ambiente do seu projeto com python -m pip install detecta e passe os dados de exemplo para detect_peaks():
data = [1, 3, 7, 1, 2, 6, 0, 5, 0, 4]
try:
from detecta import detect_peaks
except ImportError:
print("Install detecta with: python -m pip install detecta")
else:
indices = detect_peaks(data)
values = [data[index] for index in indices]
print("indices:", list(indices))
print("values:", values)
Para a sequência de exemplo, os índices esperados dos picos, começando em zero, são [2, 5, 7], correspondentes aos valores [7, 6, 5]. As evidências de execução fornecidas confirmam apenas a mensagem de dependência ausente; portanto, esse resultado do detecta é uma comparação esperada, não uma saída observada durante a execução. Mantenha a proteção da importação: quando detecta não estiver disponível, o código imprime o comando de instalação em vez de tentar detectar picos.
Escolha um método para detectar picos
Use a comparação com NumPy quando máximos estritos em relação aos vizinhos imediatos forem a regra completa de que você precisa e quiser ver a lógica diretamente. Escolha scipy.signal.find_peaks() quando for importante filtrar por condições como altura, espaçamento, proeminência ou largura. Use scipy.signal.argrelextrema() quando a vizinhança de comparação e o comparador forem centrais para sua definição de extremo. Considere detecta.detect_peaks() se a API de terceiros atender às necessidades do seu projeto e você estiver disposto a adicionar essa dependência.
Todas as posições retornadas são índices começando em zero e referentes à sequência de entrada. Antes de interpretar o resultado, compare a definição do método com seus dados: o tratamento das extremidades, dos platôs e das condições de filtragem varia. Os exemplos acima tratam de máximos locais em dados numéricos unidimensionais; para detectar picos em várias dimensões, é necessário um método adequado a esse formato de dados.