numpyとscipyの階乗

2014年02月13日に質問されました。  ·  閲覧回数 138.5k回  ·  ソース

MOON picture
2014年02月13日

どちらが速いかを確認するために、numpyとscipyから階乗関数を個別にインポートするにはどうすればよいですか?

私はすでにimportmathによってpython自体から階乗をインポートしました。 ただし、numpyやscipyでは機能しません。

回答

Ashwini Chaudhary picture
2014年02月13日
73

次のようにインポートできます。

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.factorialnumpy.math.factorialは、単にmath.factorialエイリアス/参照であるように見えます。つまり、 scipy.math.factorial is math.factorialnumpy.math.factorial is math.factorialは両方ともTrue与えるはずです。

Yuxiang Wang picture
2014年02月13日
53

scipy.math.factorialnumpy.math.factorialmath.factorialは同じ関数であると指摘することで、Ashwiniの答えは素晴らしいです。 ただし、 scipy.special.factorialが異なるというJanneが言及したものを使用することをお勧めします。 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ループを実行するよりもコーディングが簡単で高速になります。

Janne Karila picture
2014年02月13日
27

SciPyには関数scipy.special.factorial (以前のscipy.misc.factorial )があります

>>> import math
>>> import scipy.special
>>> math.factorial(6)
720
>>> scipy.special.factorial(6)
array(720.0)
Stefan Gruenwald picture
2014年04月02日
5
    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))
sudheer naidu picture
2019年06月13日
3

enter image description here

階乗に対して前述のさまざまな関数をさまざまな人が実行した後、math.factorialが階乗を計算するのに最も速いことがわかりました。

添付の画像でさまざまな機能の実行時間を見つける

SeF picture
2015年06月04日
1

いくつかの自家製階乗関数を別のモジュールutils.pyに保存し、それらをインポートして、timeitを使用して、scipy、numpy、およびmathでパフォーマンスを事前定義されたものと比較できます。 この場合、StefanGruenwaldによって最後に提案された外部メソッドとして使用しました。

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-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