とらりもんHOME  Index  Search  Changes  Login

とらりもん - python入門: numpyモジュール Diff

  • Added parts are displayed like this.
  • Deleted parts are displayed like this.

 pythonは, 四則演算やべき乗, 剰余などはできるが, それ以上の数学処理の多く, たとえばsinやcos, expなどの関数や, 行列計算などは標準的な機能としては持っていない。そのような機能は, 「{{fontc(モジュール, red)}}」として提供される。

 モジュールとは, pythonが本来は持っていない機能を追加するパッケージである。用途に応じて様々なモジュールがある。ユーザーが自分なりのモジュールを作ることもできる。とはいえ, 「python使うならこのモジュールは必須だろ!」みたいなモジュールもある。まずそれを使ってみよう。その代表は{{fontc(numpy,red)}}(ナムパイ)モジュールである。

 まずpythonシェル(ipython3)を立ち上げよう。そして, 以下のコマンドを打ってみる:
numpy.exp(1)
たぶんエラーが出るだろう。そこで, 以下のようなコマンドを打つ(意味はあとでわかる):
import numpy
そして再度, 上のコマンドを打ってみよう:
numpy.exp(1)
すると, 2.718...というネイピア数, つまりeの1乗が表示される。import numpyというコマンドで, numpyというモジュールが君のpythonシェルに追加されたのだ。その後は, 「numpy.なんちゃら」という形で, numpyモジュールの機能(命令など)が使えるのだ。numpy.exp()はeのべき乗を求める関数である。

 ではちょっとnumpyで遊んでみよう。

[レポート課題9-1] 以下を打って, 結果を報告せよ。
numpy.pi
numpy.tan(numpy.pi/4)
numpy.log(2)
このnumpy.logは対数を求めるコマンドだが, 底は何だろうか?

 では, いったんpythonシェルを抜け出よう。そして再びpythonシェルに入ってみよう。すると,
numpy.exp(1)
という命令は, 使えなくなってしまっている。このように, インポートしたモジュールは, pythonシェルが終わると(またはpythonスクリプトが終わると)忘れ去られてしまう。また使いたければまたインポートする必要がある。

 ところで, numpyはとてもよく使うモジュールなので, 何回もいちいちnumpy.を打つのはめんどくさい。そこで, numpy.というのを省略形でも許されるようにすることができる。こうやるのだ:
import numpy as np
np.exp(1)
np.pi
np.tan(np.pi/4)
np.log(2)
このように, インポートのときに, 適当な短縮形(この場合はnp)をasという語のあとにつけることで, そのモジュール(この場合はnumpy)を短縮形で呼ぶことができる。ちなみにnumpyの短縮形はnpでなくてもnでもnpでもなんでもよいのだが, pythonの文化として{{fontc(numpyはnpと短縮するのが暗黙の約束, red)}}になっている(笑)。

!numpy.ndarrayクラス

ところで, numpyには, 前回学んだリストによく似た, numpy.ndarrayというクラスがある。これは数値を扱うために特別に拡張されたリストのようなものである。それを学ぼう。まず, numpyがnpという短縮形でインポートされている(import numpy as npが既に打たれている)として, 以下をやってみよう。これは前回学んだリストだ:
[1, 2, 3]
その結果は[1, 2, 3]である。
[1, 2, 3]*2
その結果は[1, 2, 3, 1, 2,3]である。このようにリストに*2をすると, 同じ内容が2回繰り返される長いリストになる。このことも前回学んだ。

 では, 次はどうだろう:
np.array([1, 2, 3])
すると, array([1, 2, 3])と出る。これはもはやリストではなく, numpy.ndarrayというクラスのインスタンスである! そして, np.arrayというのは, リストをnumpy.ndarrayクラスに変換する命令である。確認しておこう:
type(np.array([1, 2, 3]))
すると, 確かにnumpy.ndarrayと出るだろう。このあたり, 何のことかよくわからない, という人も大丈夫。そのうち慣れる。

では, 以下をどんどん打っていこう:
np.array([1, 2, 3])*2
すると, array([2, 4, 6])と出るではないか! なんと, 各要素が2倍されている。では次を打つとどうだろう?
np.array([1, 2, 3])**2
2**np.array([1, 2, 3])
np.exp(np.array([1, 2, 3]))
その結果は, それぞれ
array([1, 4, 9])
array([  2.71828183,   7.3890561 ,  20.08553692])
となる。最初のは各要素の2乗, 次のは2の各要素乗, 最後は各要素のexpが計算されている。このような芸当は, リストでは無理である!

[レポート課題9-2] 上のような計算をリストでやろうとしてみよ。つまり, 以下の命令をやってみよ:
[1, 2, 3]**2
2**[1, 2, 3]
np.exp([1, 2, 3])
(いずれもエラーが出るだろう!)

このように, np.ndarrayは, 数値の集まり(ベクトルや行列)を表現するのに便利である。

!等差数列を作るnumpy.arange()関数
以下を打ってみよう:
np.arange(0,10)
np.arange(0,10,2)
np.arange(0,10,0.5)
np.arange(10,0,-1)
np.arange(3,9,0.3)
これらはいずれもnumpy.ndarrayのインスタンス(つまり数ベクトル, 言い換えれば数列)を作るのだが,順にそれぞれ
* 0から始まって10の手前までの, 公差1の数列(公差が1のときは省略可能)
* 0から始まって10の手前までの, 公差2の数列
* 0から始まって10の手前までの, 公差0.5の数列
* 10から始まって0の手前までの, 公差-1の数列, つまり10から1ずつ減っていって1までの数列
* 3から始まって9の手前までの, 公差0.3の数列
を表す。

[レポート課題9-3] 初項100, 最終項200, 公差5の等差数列をnumpy.ndarrayのインスタンスとして作るコマンドを述べよ。

!数列の一部(部分数列)を抜き出す
 numpy.ndarrayで表される数列は, その一部を簡単に抜き出すことができる。以下, 打ってみよう:
a=np.arange(0,20)
a
このaは, 0以上20未満の整数を順に20個並べたものだ。では以下を打ってみよう:
a[2:5]
これは, aの第2項(項番号は0から始まるので, 先頭から3番めの項)から第4項(先頭から5番めの項)までを切り出した数列である。このように,
始まりの項番号:(終わりの項番号+1)
と指定することで, numpy.ndarrayの数列の一部を取り出すことができる。さらに, 次を打ってみよう:
a[3:10:2]
これは, 第3項から第9項までの抜き出しだが, 2項づつ(1項とばしで)切り出す。このように, 最後に:をつけてもうひとつ数を指定することで, 1つずつではない間隔での抽出ができる。

 では, 以下はどうだろう?
a[::2]
これは, 最初から最後までを, 2項ずつ(1項とばしで)切り出す。このように, 範囲指定の値(項番号)を省略すると, pythonは自動的に最初や最後の項と解釈してくれる。では, 次はどうだろう?
a[::-1]
なんと, 数列が逆順になってしまった! このように, ::-1とすることで, 数列の順序をひっくりかえすことができる。

[レポート課題9-4] 以下の命令は, それぞれ何を作るか?
2**np.arange(0,10)
2**np.arange(0,10)[2:9:3]
3*2**np.arange(0,10)

[レポート課題9-5] 初項8, 公比0.5, 項数10の等差数列を等比数列をnp.ndarrayのインスタンスとして作成せよ。