静かなる名辞

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



【python】numpyでの等比数列の作り方

 ※2018年9月2日追記

 昔こんな記事を書きましたが、改めて確認したところnumpyの機能で普通に書けました。

 その方法は追記に記したので、本文は読み飛ばしてください。

 内容そのものは記録として残しておきます。


 等比数列がほしくなった。作り方をメモしておく。

 目次

比が決まっている場合

 たとえば、3倍ずつ増えていく等比数列がほしいとしよう。

 これは次のように簡単に作れる。

>>> import numpy as np
>>> rates = np.ones(10) * 3
>>> rates
array([3., 3., 3., 3., 3., 3., 3., 3., 3., 3.])
>>> rates ** np.arange(10)
array([1.0000e+00, 3.0000e+00, 9.0000e+00, 2.7000e+01, 8.1000e+01,
       2.4300e+02, 7.2900e+02, 2.1870e+03, 6.5610e+03, 1.9683e+04])

 できたけど、これは面白くもなんともないのだった。

範囲とnが決まっている場合

 たとえば「1から10までの範囲で10個ほしい!」というパターン。これは一筋縄ではいかなさそうである。

 幸い、np.logspaceという便利そうなものがある。

 numpy.logspace — NumPy v1.15 Manual

 これを使えばたぶんできるだろう。

>>> import numpy as np
>>> np.logspace(1,10,10)
array([1.e+01, 1.e+02, 1.e+03, 1.e+04, 1.e+05, 1.e+06, 1.e+07, 1.e+08,
       1.e+09, 1.e+10])

 期待通り動かないのだった。baseというオプションがあり、default=10で、その1,2,3,...,9,10乗が得られている訳である。

 ちょっと意図と違うので、こうしてみた。

>>> np.logspace(0, np.log10(10), 10)
array([ 1.        ,  1.29154967,  1.66810054,  2.15443469,  2.7825594 ,
        3.59381366,  4.64158883,  5.9948425 ,  7.74263683, 10.        ])

 成功した。冷静に考えると、この場合はこれで良い(log10(10)は1だ・・・)。

>>> np.logspace(0, 1, 10)
array([ 1.        ,  1.29154967,  1.66810054,  2.15443469,  2.7825594 ,
        3.59381366,  4.64158883,  5.9948425 ,  7.74263683, 10.        ])

 でもまあ、log10を使う方法だと他の範囲にも対応できる。

>>> np.logspace(0, np.log10(20), 10)
array([ 1.        ,  1.39495079,  1.94588772,  2.71441762,  3.78647901,
        5.2819519 ,  7.368063  , 10.27808533, 14.33742329, 20.        ])

 たとえば23から54まで10個取りたい場合は、どうしたら良いのだろう? こうする。

>>> np.logspace(np.log10(23), np.log10(54), 10)
array([23.        , 25.28791009, 27.80340855, 30.56913458, 33.60997942,
       36.95331033, 40.62921692, 44.67078193, 49.114379  , 54.        ])

 これで一般化できたので、いつでも使えるようになったと思う。

追記

 何もしなくても等比数列を生成するnumpy.geomspaceが用意されていて、普通にこちらでできました。

numpy.geomspace — NumPy v1.15 Manual

>>> import numpy as np
>>> np.geomspace(1, 10, 10)
array([ 1.        ,  1.29154967,  1.66810054,  2.15443469,  2.7825594 ,
        3.59381366,  4.64158883,  5.9948425 ,  7.74263683, 10.        ])
>>> np.geomspace(23, 54, 10)
array([23.        , 25.28791009, 27.80340855, 30.56913458, 33.60997942,
       36.95331033, 40.62921692, 44.67078193, 49.114379  , 54.        ])

 geometric progressionという英単語に馴染みがなくて、記事を書いたときには見つけられなかったのですが……。

 精進しようと思います。