numpy 和 scipy 中的阶乘
Posted
技术标签:
【中文标题】numpy 和 scipy 中的阶乘【英文标题】:Factorial in numpy and scipy 【发布时间】:2014-03-12 07:23:17 【问题描述】:如何分别从 numpy 和 scipy 导入阶乘函数以查看哪个更快?
我已经通过 import math 从 python 本身导入了阶乘。但是,它不适用于 numpy 和 scipy。
【问题讨论】:
【参考方案1】:您可以像这样导入它们:
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
和numpy.math.factorial
似乎只是math.factorial
的别名/引用,即scipy.math.factorial is math.factorial
和numpy.math.factorial is math.factorial
都应该给出True
。
【讨论】:
【参考方案2】: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])
因此,如果您对 np.ndarray 进行阶乘,那么来自 scipy 的那个将比执行 for 循环更容易编码和更快。
【讨论】:
scipy.misc.factorial
的好处是它只计算一次阶乘——对于数组中的最大数。所有其他都被计算为过程中的副作用。
弃用警告:在 scipy 1.0.0.使用scipy.special.factorial
如果需要,scipy.special.factorial
还可以使用 gamma 函数估计值。【参考方案3】:
SciPy 有函数scipy.special.factorial
(以前的scipy.misc.factorial
)
>>> import math
>>> import scipy.special
>>> math.factorial(6)
720
>>> scipy.special.factorial(6)
array(720.0)
【讨论】:
【参考方案4】: 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))
【讨论】:
【参考方案5】:在不同的人对阶乘运行不同的上述函数后,结果证明 math.factorial 是计算阶乘的最快速度。
在附图中查找不同功能的运行时间
【讨论】:
【参考方案6】:您可以将一些自制的阶乘函数保存在单独的模块 utils.py 中,然后导入它们并使用 timeit 在 scipy、numpy 和 math 中将其性能与预定义的函数进行比较。 在这种情况下,我使用了 Stefan Gruenwald 最后提出的外部方法:
import numpy as np
def factorial(n):
return reduce((lambda x,y: x*y),range(1,n+1))
主要代码(我在另一篇文章中使用了 JoshAdel 提出的框架,查找 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)
提供:
method1 0.0195569992065
method2 0.00638914108276
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Process finished with exit code 0
【讨论】:
以上是关于numpy 和 scipy 中的阶乘的主要内容,如果未能解决你的问题,请参考以下文章
如何检查 NumPy 和 SciPy 中的 BLAS/LAPACK 链接?