静かなる名辞

pythonとプログラミングのこと


【python】numpyで任意の底でlog

 任意の底でlogを計算したいときがあります。

 結論から言うと、そういう関数は用意されていません。ただし、簡単な処理で実現することは可能です。

 ちなみに、デフォルトで用意されているのはlog(eが底), log10, log2のみです。

Mathematical functions — NumPy v1.16 Manual

 任意の底でやりたい場合は、log(eが底)で一旦計算してから、log(使いたい底)で割ってあげます。

>>> import numpy as np
>>> a = 59**5
>>> np.log(a)/np.log(59)
5.0


 対数の性質を思い出せばそれほど難しくないのですが、デフォルトではできないのが少し不便といえば不便ですね。ちなみに、分母側が変わらない場合は、先に計算して変数に格納しておくことで若干の高速化が可能です。

 この処理、math.logなら一発でできるんですが。

>>> import math
>>> math.log(a, 59)
5.0

 おまけ。

 最初、すごく大きな値でやろうとしたらエラーが出ました。

>>> a = 59**100
>>> np.log(a)/np.log(59)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'log'
>>> a
1216749465718417874559491998513561121966072058691773438388982975785993854256756157494173512672915757033875049659241870497099358702416318491812748479721683887882543089775014614001

 これは多倍長整数だから表現できているのであって、int64とかでは表現できないためエラーになるということですね。floatに直したら行けました。

>>> float(a)
1.2167494657184178e+177
>>> np.log(float(a))/np.log(59)
100.0

 精度は有効桁数に縛られますが(doubleの有効桁数はたかだか15桁)、まあ割とどうでも良い。