2015-11-26 5 views
5

Funzione argrelextrema da scipy.signal non rileva estremi piatti. Esempio:argrelextrema e flat extrema

import numpy as np 
from scipy.signal import argrelextrema 
data = np.array([ 0, 1, 2, 1, 0, 1, 3, 3, 1, 0 ]) 
argrelextrema(data, np.greater) 
(array([2]),) 

viene rilevato il primo max (2), il secondo max (3, 3) non viene rilevato.

Qualsiasi soluzione per questo comportamento? Grazie.

risposta

12

Risposta breve: Probabilmente argrelextrema non sarà abbastanza flessibile per l'attività. Potresti scrivere la tua funzione in base alle tue esigenze. risposta


più lunga: Stai obbligata ad utilizzare argrelextrema? In caso affermativo, è possibile giocare con gli argomenti comparator e order di argrelextrema (vedere reference).

Per il semplice esempio, sarebbe sufficiente scegliere np.greater_equal come comparator.

>>> data = np.array([ 0, 1, 2, 1, 0, 1, 3, 3, 1, 0 ]) 
>>> print(argrelextrema(data, np.greater_equal,order=1)) 
(array([2, 6, 7]),) 

Nota però che in questo modo

>>> data = np.array([ 0, 1, 2, 1, 0, 1, 3, 3, 4, 1, 0 ]) 
>>> print(argrelextrema(data, np.greater_equal,order=1)) 
(array([2, 6, 8]),) 

si comporta in modo diverso che si sarebbe probabilmente desidera, trovando il primo 3 e la 4 come massimi, dal momento che argrelextrema ora vede tutto come un massimo che è maggiore o uguale ai suoi due vicini più vicini. Ora puoi utilizzare l'argomento order per decidere quanti vicini deve tenere questo confronto: scegliere order=2 cambierebbe il mio esempio superiore per trovare solo 4 come massimo.

>>> print(argrelextrema(data, np.greater_equal,order=2)) 
(array([2, 8]),) 

V'è, tuttavia, un aspetto negativo di questo - cambiamo i dati una volta di più:

>>> data = np.array([ 0, 1, 2, 1, 0, 1, 3, 3, 4, 1, 5 ]) 
>>> print(argrelextrema(data, np.greater_equal,order=2)) 
(array([ 2, 10]),) 

aggiunta di un altro picco come un ultimo valore ti impedisce di trovare il vostro picco a 4, come argrelextrema è ora vedendo un secondo vicino che è maggiore di 4 (che può essere utile per dati rumorosi, ma non necessariamente per il comportamento previsto in tutti i casi).


Utilizzando argrelextrema, si sarà sempre limitata alle operazioni binarie tra un numero fisso di vicini di casa. Si noti, tuttavia, che tutto il argrelextrema nell'esempio sopra riportato restituisce n, se data[n] > data[n-1] and data[n] > data[n+1]. Potresti facilmente implementarlo tu stesso e quindi perfezionare le regole, ad esempio controllando il secondo vicino nel caso in cui il primo vicino abbia lo stesso valore.


Per ragioni di completezza, sembra che ci sia una funzione più elaborato in scipy.signal, find_peaks_cwt. Tuttavia, non ho esperienza nell'usarlo e quindi non posso darti maggiori dettagli a riguardo.

+0

Per altri algoritmi di rilevamento del picco, è anche possibile controllare https: // github.com/MonsieurV/py-findpeaks 'argrelextrema' non è davvero la scelta più facile quando si vuole armeggiare con il comportamento dell'algoritmo. –