2015-03-07 6 views

risposta

1

Non penso che questo possa essere fatto facilmente in NumPy da solo, senza usare un ciclo.

Un'idea basata su array sarebbe quella di calcolare la matrice M_ij = .95 ** i * a [N-j] (dove N è il numero di elementi in a). I numeri che stai cercando si trovano sommando le voci in diagonale (con costante i-j). È possibile utilizzare in tal modo utilizzare più numpy.diagonal(…).sum().

Il buon vecchio algoritmo che si struttura è più chiaro e probabilmente abbastanza veloce già (altrimenti è possibile utilizzare Cython).

Fare quello che vuoi con NumPy senza un singolo loop suona come una magia per me. Un saluto affettuoso a chiunque riesca a tirarlo fuori.

8

Stai chiedendo un semplice IIR Filter. SciPy di ​​lfilter() è fatto per questo:

import numpy as np 
from scipy.signal import lfilter 

data = np.array([2, 3, 0, 0, 4, 3], dtype=float) # lfilter wants floats 

# Conventional approach: 
result_conv = [] 
last_value = 0 
for elmt in data: 
    last_value = (last_value + elmt)*.95 
    result_conv.append(last_value) 

# IIR Filter: 
result_IIR = lfilter([.95], [1, -.95], data) 

if np.allclose(result_IIR, result_conv, 1e-12): 
    print("Values are equal.") 
+2

Considererei l'uso di 'xx = np.array ([2, 3, 0, 0, 4, 3], dtype = np.float64)' invece qui –

+0

Punto valido. Riesero a riprodurre il mio codice e sembra che il reclamo di '' lfilter() '' sia venuto da un altro problema. – Dietrich

4

Se siete solo che fare con una serie 1D, poi a corto di comodità SciPy o la scrittura di un costume ridurre ufunc per NumPy, allora in Python 3.3+, è possibile utilizzare itertools.accumulate, es:

from itertools import accumulate 

a = (2,3,0,0,4,3) 
y = list(accumulate(a, lambda x,y: (x+y)*0.95)) 
# [2, 4.75, 4.5125, 4.286875, 7.87253125, 10.3289046875] 
0

Numba fornisce un modo semplice per vectorize una funzione, creando un universal function (fornendo così ufunc.accumulate):

import numpy 
from numba import vectorize, float64 

@vectorize([float64(float64, float64)]) 
def f(x, y): 
    return 0.95 * (x + y) 

>>> a = numpy.array([2, 3, 0, 0, 4, 3]) 
>>> f.accumulate(a) 
array([ 2.  , 4.75  , 4.5125 , 4.286875 , 
     7.87253125, 10.32890469])