Comparison numpy array loops. "np.vectorize" is the best option.
import numpy as np
from math import sin as sn
import time
# Number of test points
N_point = 1000
# Define a custom function with some if-else loops
def myfunc(x,y):
if (x>0.5*y and y<0.3):
return (sn(x-y))
elif (x<0.5*y):
return 0
elif (x>0.2*y):
return (2*sn(x+2*y))
else:
return (sn(y+x))
# List of stored elements, generated from a Normal distribution
lst_x = np.random.randn(N_point)
lst_y = np.random.randn(N_point)
lst_result = []
## First, plain vanilla for-loop ##
t1=time.time()
for i in range(len(lst_x)):
x = lst_x[i]
y= lst_y[i]
if (x>0.5*y and y<0.3):
lst_result.append(sn(x-y))
elif (x<0.5*y):
lst_result.append(0)
elif (x>0.2*y):
lst_result.append(2*sn(x+2*y))
else:
lst_result.append(sn(y+x))
t2=time.time()
print("\nTime taken by the plain vanilla for-loop\n----------------------------------------------\n{} us".format(1000000*(t2-t1)))
## List comprehension ##
print("\nTime taken by list comprehension and zip\n"+'-'*40)
%timeit lst_result = [myfunc(x,y) for x,y in zip(lst_x,lst_y)]
## Map() function ##
print("\nTime taken by map function\n"+'-'*40)
%timeit list(map(myfunc,lst_x,lst_y))
## Numpy.vectorize method ##
print("\nTime taken by numpy.vectorize method\n"+'-'*40)
vectfunc = np.vectorize(myfunc,otypes=[np.float],cache=False)
%timeit list(vectfunc(lst_x,lst_y))
## Results:
# Time taken by the plain vanilla for-loop
# ----------------------------------------------
# 2000.0934600830078 us
#
# Time taken by list comprehension and zip
# ----------------------------------------
# 1000 loops, best of 3: 810 µs per loop
#
# Time taken by map function
# ----------------------------------------
# 1000 loops, best of 3: 726 µs per loop
#
# Time taken by numpy.vectorize method
# ----------------------------------------
# 1000 loops, best of 3: 516 µs per loop < -----------WINNER!!!!!!!!