Créer les tableaux de gamme en fonction des limites de iterator à l'aide NumPy's powerful broadcasting feature
puis utiliser directement la formule, comme si -
mask_mat = np.zeros((1280,720),np.bool)
I = np.arange(640,1220)[:,None]
J = np.arange(0,360)
mask_mat[640:1220,0:360] = ((J > (-9/16*I + 690))&(J < (-9/16*I + 750)))
notez-de l'étape: I = np.arange(640,1220)[:,None]
. Nous y ajoutons un nouvel axe, qui représente le premier axe de la sortie. Cela introduit la fonction de diffusion pour effectuer des ajouts élémentaires de manière vectorisée. L'autre tableau de plage J
suit le deuxième axe de la sortie.
Pour améliorer encore les performances, nous pouvons souhaiter calculer -9/16*I
et le réutiliser aux deux emplacements de la formule.
test Runtime
approches -
# Original loopy soln
def loopy_app():
mask_mat = np.zeros((1280,720),np.bool)
for i in range(640,1220):
for j in range(0,360):
if ((j > (-9/16*i + 690))&(j < (-9/16*i + 750))):
mask_mat[i][j] = True;
return mask_mat
# @donkopotamus's soln
def fromfunc_app():
return np.fromfunction(
lambda i, j: ((640 <= i) & (i < 1220) &
(j < 360) &
(j > (-9/16 * i + 690)) &
(j < (-9/16*i + 750))), (1280, 720))
# Proposed in this post
def vectorized_app():
mask_mat = np.zeros((1280,720),np.bool)
I = np.arange(640,1220)[:,None]
J = np.arange(0,360)
mask_mat[640:1220,0:360] = ((J > (-9/16*I + 690))&(J < (-9/16*I + 750)))
return mask_mat
synchronisations -
In [86]: %timeit loopy_app()
10 loops, best of 3: 29.7 ms per loop
In [87]: %timeit fromfunc_app()
100 loops, best of 3: 11.9 ms per loop
In [88]: %timeit vectorized_app()
1000 loops, best of 3: 370 µs per loop
In [90]: 29700/370.0
Out[90]: 80.27027027027027
80x+
avec l'approche speedup vectorisé basée diffusion!
boost plus avec numexpr
Nous pourrions augmenter davantage en apportant numexpr
module pour effectuer ces opérations arithmétiques comme une expression:
import numexpr as ne
def vectorized_expr_app():
mask_mat = np.zeros((1280,720),np.bool)
I = np.arange(640,1220)[:,None]
J = np.arange(0,360)
vals = ne.evaluate('((J > (-9/16*I + 690))&(J < (-9/16*I + 750)))')
mask_mat[640:1220,0:360] = vals
return mask_mat
synchronisations:
In [101]: %timeit vectorized_expr_app()
1000 loops, best of 3: 321 µs per loop
In [102]: 29700/321.0
Out[102]: 92.5233644859813
90x+
accélérer maintenant!
ce que je cherche, je vous remercie beaucoup –