2017-07-06 4 views
3

Comment vectoriser le calcul suivant si a et b sont des tableaux numpy de taille appropriée?Comment vectoriser ce calcul en numpy

total = a[0] 
for ix in range(1, len(a)): 
    total = total*b[ix-1] + a[ix] 
+0

calculs Normalement du type 'a [i] = f (a [i-1])' ne sont pas vectorisable à moins que vous avez de la chance et peut faire un [ 'ufunc'] (https://docs.scipy.org/doc/numpy/reference/ufuncs.html) astuce. Je ne vois pas un moyen de faire ça ici. –

Répondre

4

Qu'à cela ne tienne, il y a un truc qui fonctionne ufunc si vous faites une algèbre. Dans ce cas le ufunc est multiply et l'astuce est accumulate.

c = np.r_[np.multiply.accumulate(b[0:-1][::-1])[::-1], 1] 
total2 = np.sum(a * c) 

Ce que cela fait: Algébriquement, vous sommateur a[i] fois le produit de b[i:] sur for i in range(a.size). Pour ce faire, retournez b et obtenez le produit en cours d'exécution de tous sauf le dernier numéro (en supposant que a et b ont la même longueur), puis retournez-le. La dernière valeur doit être 1 car la valeur finale a vient d'être ajoutée.

Test

a = np.random.randint(1, 10, 40) 
b = 1 + np.random.rand(40) 

total = a[0] 
for ix in range(1, len(a)): 
    total = total*b[ix-1] + a[ix] 

total 
278443993.10494208 

total2 
278443993.10494208 
+1

La variation suivante de l'excellente réponse de @ DanielF améliore la vitesse de> = 2x: 'np.sum (np.cumprod (b [-2 :: - 1]) [:: - 1] * a [: - 1]) + un [-1] ' –