How can I import factorial function from numpy and scipy separately in order to see which one is faster?
I already imported factorial from python itself by import math. But, it does not work for numpy and scipy.
06 Answers
You can import them like this:
In [7]: import scipy, numpy, math In [8]: scipy.math.factorial, numpy.math.factorial, math.factorial Out[8]: (<function math.factorial>, <function math.factorial>, <function math.factorial>) scipy.math.factorial and numpy.math.factorial seem to simply be aliases/references for/to math.factorial, that is scipy.math.factorial is math.factorial and numpy.math.factorial is math.factorial should both give True.
The answer for Ashwini is great, in pointing out that scipy.math.factorial, numpy.math.factorial, math.factorial are the same functions. However, I'd recommend use the one that Janne mentioned, that scipy.special.factorial is different. The one from scipy can take np.ndarray as an input, while the others can't.
In [12]: import scipy.special In [13]: temp = np.arange(10) # temp is an np.ndarray In [14]: math.factorial(temp) # This won't work --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-14-039ec0734458> in <module>() ----> 1 math.factorial(temp) TypeError: only length-1 arrays can be converted to Python scalars In [15]: scipy.special.factorial(temp) # This works! Out[15]: array([ 1.00000000e+00, 1.00000000e+00, 2.00000000e+00, 6.00000000e+00, 2.40000000e+01, 1.20000000e+02, 7.20000000e+02, 5.04000000e+03, 4.03200000e+04, 3.62880000e+05]) So, if you are doing factorial to a np.ndarray, the one from scipy will be easier to code and faster than doing the for-loops.
3SciPy has the function scipy.special.factorial (formerly scipy.misc.factorial)
>>> import math >>> import scipy.special >>> math.factorial(6) 720 >>> scipy.special.factorial(6) array(720.0) 0 from numpy import prod def factorial(n): print prod(range(1,n+1)) or with mul from operator:
from operator import mul def factorial(n): print reduce(mul,range(1,n+1)) or completely without help:
def factorial(n): print reduce((lambda x,y: x*y),range(1,n+1)) after running different aforementioned functions for factorial, by different people, turns out that math.factorial is the fastest to calculate the factorial.
find running times for different functions in the attached image
You can save some homemade factorial functions on a separate module, utils.py, and then import them and compare the performance with the predefinite one, in scipy, numpy and math using timeit. In this case I used as external method the last proposed by Stefan Gruenwald:
import numpy as np def factorial(n): return reduce((lambda x,y: x*y),range(1,n+1)) Main code (I used a framework proposed by JoshAdel in another post, look for how-can-i-get-an-array-of-alternating-values-in-python):
from timeit import Timer from utils import factorial import scipy n = 100 # test the time for the factorial function obtained in different ways: if __name__ == '__main__': setupstr=""" import scipy, numpy, math from utils import factorial n = 100 """ method1=""" factorial(n) """ method2=""" scipy.math.factorial(n) # same algo as numpy.math.factorial, math.factorial """ nl = 1000 t1 = Timer(method1, setupstr).timeit(nl) t2 = Timer(method2, setupstr).timeit(nl) print 'method1', t1 print 'method2', t2 print factorial(n) print scipy.math.factorial(n) Which provides:
method1 0.0195569992065 method2 0.00638914108276 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 Process finished with exit code 0
