2015-09-15 12 views
7

Sono nuovo in Python e sto cercando di eseguire alcune operazioni di elaborazione del segnale di base e sto avendo un serio problema di prestazioni. C'è un trucco Python per fare questo in modo vettorializzato? Fondamentalmente sto cercando di implementare un filtro del primo ordine, ma dove le caratteristiche del filtro possono cambiare da un campione all'altro. Se fosse solo un filtro, userei numpy.signal.lfilter(), ma è un po 'più complicato. Ecco il frammento di codice che va molto lentamente:Iterazione veloce di array numpy

#filter state 
state = 0 

#perform filtering 
for sample in amplitude: 
    if(sample == 1.0): #attack filter 
     sample = (1.0 - att_coeff) * sample + att_coeff * state 
    else: #release filter 
     sample = (1.0 - rel_coeff) * sample + rel_coeff * state 

    state = sample 

risposta

0

Ogni voce richiede l'inserimento precedente, e la voce precedente deve essere calcolato prima di poter calcolare la voce corrente. Quindi ogni voce deve essere calcolata in serie e non è possibile farlo in modo vettorizzato (cioè mappato, parallelo).

7

Si potrebbe considerare l'utilizzo di uno dei convertitori python-to-native-code, tra , numba o pythran.

Per esempio, esegue il codice originale con timeit mi da:

$ python -m timeit -s 'from co import co; import numpy as np; a = np.random.random(100000)' 'co(a, .5, .7)' 
10 loops, best of 3: 120 msec per loop 

Mentre annotare con pythran, come in:

#pythran export co(float[], float, float) 
def co(amplitude, att_coeff, rel_coeff): 
    #filter state 
    state = 0 

    #perform filtering 
    for sample in amplitude: 
     if(sample == 1.0): #attack filter 
      state = (1.0 - att_coeff) * sample + att_coeff * state 
     else: #release filter 
      state = (1.0 - rel_coeff) * sample + rel_coeff * state 
    return state 

e compilarlo con

$ pythran co.py 

mi dà:

$ python -m timeit -s 'from co import co; import numpy as np; a = np.random.random(100000)' 'co(a, .5, .7)' 

1000 cicli, migliori di 3: 253 usec per loop

Questo è circa un aumento di velocità x 470, mi aspetto Numba e Cython per dare incrementi nella velocità simili!