2014-07-05 8 views
6

Hi python enthusiasts!SciPy medfilt risultato errato

Attualmente sto lavorando con il filtro dei segnali a scopo di ricerca e ho deciso di utilizzare SciPy. Niente di speciale, solo automazione del lavoro di routine.

Quindi, ecco il codice

from scipy.signal import medfilt 
print(medfilt([2,6,5,4,0,3,5,7,9,2,0,1], 5)) 

Ma la questione è che sequense restituito viene calcolato sbagliato

SciPy: [ 2. 4. 4. 4. 4. 4. 5. 5. 5. 2. 1. 0.] 
Me : [ 5. 4.5 4. 4. 4. 4. 5. 5. 5. 2. 1.5 1.] 

Sembra essere, che gli sviluppatori di pacchetto incasinato un dettaglio. Quando apertura (il kernel in termini di SciPy) è maggiore della finestra da analizzare, c'è un'altra regola di filtraggio.

Ad esempio con kernel=5 sottosequenza filtrata di [2, 6, 5] ha mediana 5 e non 2 come SciPy calcolato no? E allo stesso modo, se kernel=5 per le sottosequenze [2,6,5,4] le mediane sono 5 e 4 dobbiamo prendere una media tra loro, quindi la mediana è 4,5.

Qualcuno può spiegarmi chi ha ottenuto il risultato giusto in questo caso?

risposta

13

Credo che sia tu che SciPy abbiate risultati corretti. La differenza sta in ciò che accade ai confini, ma credo che sia tu che SciPy abbiano fatto delle scelte valide.

La domanda è che cosa dovrebbe accadere quando la finestra scorrevole è ai bordi e non ci sono dati validi da utilizzare per compilare la finestra scorrevole.

Hai scelto di prendere la mediana della parte valida della finestra scorrevole, il che ha senso, ma potrebbe aggiungere qualche pregiudizio perché i tuoi punti di bordo sono sovrarappresentati rispetto a tutti gli altri punti.

SciPy ha invece scelto di estendere il segnale su entrambi i lati inserendo degli zeri. Così, sui confini, SciPy è essenzialmente calcolando

>>> np.median([0, 0, 2, 6, 5]) 
2.0 
>>> np.median([0, 2, 6, 5, 4]) 
4.0 
>>> np.median([9, 2, 0, 1, 0]) 
1.0 
>>> np.median([2, 0, 1, 0, 0]) 
0.0 

Il motivo per cui SciPy fa questo è quasi sicuramente la velocità legate: è ottimizzato per fare la stessa cosa più volte, ed è molto più facile da ottimizzare median per un intero gruppo di matrici a 5 elementi rispetto all'ottimizzazione per un intero gruppo di matrici a 5 elementi e anche due matrici a 4 elementi e due matrici a 3 elementi. C'è sicuramente un argomento da fare che non dovrebbe riempire di zeri, ma piuttosto con i valori di confine, ma va notato che nessuna strategia di confine sarà perfetta; il modo ideale per affrontare i problemi di confine dipenderà dal tuo particolare segnale.

Se vedi Wikipedia's description of median filters, estendono il segnale su entrambi i lati imbottendolo con il valore ai bordi, il che sembra ragionevole. Notano anche questi tre altri modi di affrontare i problemi di confine:

  • Evitare l'elaborazione dei limiti, con o senza ritaglio del limite del segnale in seguito.
  • Recupero di voci da altri punti del segnale. Con le immagini, ad esempio, è possibile selezionare voci dal limite orizzontale o verticale lontano.
  • Riduci la finestra vicino ai limiti, in modo che ogni finestra sia piena (come hai fatto tu.)

Alla fine, è davvero necessario provare diverse opzioni e vedere cosa funziona meglio per il segnale. Un'ipotesi principale di questo tipo di filtraggio è che il segnale sarà abbastanza grande e il problema al contorno non dovrebbe mai essere così critico (poiché la maggior parte del segnale non esiste sul confine). Sarebbe bello se SciPy ti permettesse di selezionare ciò che dovrebbe fare ai confini, però!

+0

Giusto per espandere un po 'su questa risposta, chi cerca funzioni mediana rotolamento alternativi può guardare in: Pandas mediana rotolamento: http://pandas.pydata.org/pandas-docs/stable/computation.html# moving-rolling-statistics-moments e scipy.ndimage: http://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.ndimage.filters.median_filter.html – ConnectedSystems