Python numpy和scipy中的阶乘

Python numpy和scipy中的阶乘,python,numpy,scipy,Python,Numpy,Scipy,如何分别从numpy和scipy导入阶乘函数以查看哪一个更快 我已经通过导入数学从python本身导入了阶乘。但是,它不适用于numpy和scipy。您可以这样导入它们: In [7]: import scipy, numpy, math In [8]: scipy.math.factorial, numpy.math.factorial, math.factorial Out[

如何分别从numpy和scipy导入阶乘函数以查看哪一个更快


我已经通过导入数学从python本身导入了阶乘。但是,它不适用于numpy和scipy。

您可以这样导入它们:

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>)
[7]中的
:导入scipy、numpy、数学
在[8]中:scipy.math.factorial,numpy.math.factorial,math.factorial
出[8]:
(,                                                                
,                                                                
)
scipy.math.factorial
numpy.math.factorial
似乎只是/to
math.factorial
的别名/引用,也就是说
scipy.math.factorial是math.factorial
numpy.math.factorial是math.factorial。factorial
应该都给出
True
scipy的函数(以前的
scipy.misc.factorial


Ashwini的答案很好,因为他指出,
scipy.math.factorial
numpy.math.factorial
math.factorial
是相同的函数。但是,我建议使用Janne提到的函数,
scipy.special.factorial
是不同的。scipy的函数可以将
np.ndarray
作为一个函数输入,而其他人不能

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])
[12]中的
:导入scipy.special
在[13]中,temp=np.arange(10)#temp是一个np.ndarray
在[14]:math.factorial(temp)#这行不通
---------------------------------------------------------------------------
TypeError回溯(最近一次调用上次)
在()
---->1数学阶乘(临时)
TypeError:只有长度为1的数组才能转换为Python标量
在[15]中:scipy.special.factorial(temp)#这很有效!
出[15]:
数组([1.00000000e+00,1.00000000e+00,2.00000000e+00,
6.00000000e+00,2.40000000e+01,1.20000000e+02,
7.200000E+02、5.0400000E+03、4.03200000e+04、,
3.6288000E+05])
因此,如果您要对np.ndarray执行阶乘运算,那么来自scipy的一个将比执行for循环更容易编码和更快

    from numpy import prod

    def factorial(n):
        print prod(range(1,n+1))
或使用来自操作员的mul:

    from operator import mul

    def factorial(n):
        print reduce(mul,range(1,n+1))
或者完全没有帮助:

    def factorial(n):
        print reduce((lambda x,y: x*y),range(1,n+1))

您可以将一些自制的阶乘函数保存在单独的模块utils.py上,然后导入它们,并使用timeit在scipy、numpy和math中将其性能与预定义的函数进行比较。 在这种情况下,我使用了Stefan Grunwald提出的最后一种外部方法:

import numpy as np


def factorial(n):
    return reduce((lambda x,y: x*y),range(1,n+1))
主要代码(我使用了JoshAdel在另一篇文章中提出的框架,查找python中的how-can-I-get-an-array-of-alternative-values-in-python):

其中规定:

method1 0.0195569992065
method2 0.00638914108276

93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000


Process finished with exit code 0

在不同的人为阶乘运行了前面提到的不同函数之后,math.factorial是计算阶乘最快的


在所附的图像中查找不同函数的运行时间

scipy.misc.factorial的好处是它只计算数组中最大数的阶乘一次。所有其他的都是作为过程中的副作用计算的。弃用警告:在scipy 1.0.0中。使用
scipy.special.factorial
如果需要,
scipy.special.factorial
也可以使用gamma函数估计值。
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)
method1 0.0195569992065
method2 0.00638914108276

93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000


Process finished with exit code 0