Comment puis-je importer séparément les fonctions factorielles de numpy et scipy afin de voir laquelle est la plus rapide?
J'ai déjà importé factorial de python lui-même par import math. Toutefois, cela ne fonctionne pas pour numpy et scipy.
Vous pouvez les importer comme ceci:
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
et numpy.math.factorial
semblent être simplement des alias/références pour/à math.factorial
, C'est scipy.math.factorial is math.factorial
et numpy.math.factorial is math.factorial
devrait donner à la fois True
.
La réponse pour Ashwini est excellente, en soulignant que scipy.math.factorial
, numpy.math.factorial
, math.factorial
sont les mêmes fonctions. Cependant, je recommanderais d'utiliser celui que Janne a mentionné, que scipy.misc.factorial
est différent. Celui de Scipy peut prendre np.ndarray
comme une entrée, alors que les autres ne le peuvent pas.
In [12]: import scipy.misc
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.misc.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])
Donc, si vous faites factorial à un np.ndarray, celui de scipy sera plus facile à coder et plus rapide que de faire les boucles for-loop.
SciPy a la fonction scipy.special.factorial
(anciennement scipy.misc.factorial
)
>>> import math
>>> import scipy.special
>>> math.factorial(6)
720
>>> scipy.special.factorial(6)
array(720.0)
from numpy import prod
def factorial(n):
print prod(range(1,n+1))
ou avec mul de l'opérateur:
from operator import mul
def factorial(n):
print reduce(mul,range(1,n+1))
ou complètement sans aide:
def factorial(n):
print reduce((lambda x,y: x*y),range(1,n+1))
Vous pouvez enregistrer certaines fonctions factorielles personnalisées sur un module distinct, utils.py, puis les importer et comparer les performances avec celles prédéfinies, en scipy, numpy et math en utilisant timeit. Dans ce cas, j'ai utilisé comme méthode externe la dernière proposition de Stefan Gruenwald:
import numpy as np
def factorial(n):
return reduce((lambda x,y: x*y),range(1,n+1))
Code principal (j'ai utilisé un framework proposé par JoshAdel dans un autre article, cherchez comment puis-je-obtenir-un-tableau-de-valeurs-alternantes-en-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 __== '__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)
Qui fournit:
method1 0.0195569992065
method2 0.00638914108276
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Process finished with exit code 0