python入門: 9. numpyモジュール
pythonは, 四則演算やべき乗, 剰余などはできるが, それ以上の数学処理の多く, たとえばsinやcos, expなどの関数や, 行列計算などは標準的な機能としては持っていない。そのような機能は, 「モジュールやパッケージ」として提供される。
モジュールとは, pythonが本来は持っていない機能を追加するプログラムである。モジュールを集めたものがパッケージだと思ってよい(両者の区別を気にする必要は今のところ無い)。様々な用途に応じて様々なモジュールやパッケージがある。ユーザーが自分で作ることもできる。とはいえ, 「python使うならこのモジュールやパッケージは必須だろ!」みたいなものもある。その代表であるnumpy(ナムパイ)を使ってみよう。
まずpythonシェル(ipython3)またはGoogle Colaboratoryを立ち上げよう。そして, 以下のコマンドを打ってみよう:
numpy.exp(1)
たぶんエラーが出るだろう。そこで, 以下のようなコマンドを打つ(意味は後でわかる):
import numpy
そして再度, 上のコマンドを打ってみよう:
numpy.exp(1)
すると, 2.718...つまりネイピア数, つまりeの1乗が表示される。"import numpy"でnumpyというモジュールをPyhthonが準備して(読み込んで)くれたのだ。その後は, 「numpy.なんちゃら」という形で, numpyモジュールの機能(命令など)が使えるのだ。numpy.exp()はeのべき乗を求める関数である。
ではちょっとnumpyで遊んでみよう。以下を打ってみよう。それぞれどういう結果が出るだろう?
numpy.pi (結果はどうなった?) numpy.tan(numpy.pi/4) (結果はどうなった?) numpy.log(2) (結果はどうなった?)
このnumpy.logは対数を求めるコマンドだが, 底は何だろうか?
注: import numpyは1回やればその後はPythonを終了させるまではnumpyを使うことができる。しかし, いちどPythonを終了すると(Colaboratoryならしばらく放置するとそうなる)無効化される。従って, Pythonを起動するたびにインポートする必要がある。
numpyにニックネームをつける
numpyはよく使うのでいちいちキーボードで"numpy."と打つのは面倒だ。そこで"numpy."のかわりに短い省略名(ニックネーム)を使えると便利だ。それはこうやるのだ:
import numpy as np np.exp(1) (結果はどうなった?) np.pi (結果はどうなった?)
このように, インポートのときに, 適当な省略名(この場合はnp)をasという語のあとにつけることで, そのモジュール(この場合はnumpy)を省略名で呼ぶことができる。ちなみにnumpyの省略名はnpでなくてもnでもshigenでもなんでもよい。実際やってみよう:
import numpy as shigen shigen.exp(1) (結果はどうなった?) shigen.pi (結果はどうなった?)
しかしpythonの文化としてnumpyはnpと省略するのが暗黙の約束になっているので, それを踏襲するほうがよいだろう(ネット検索でも良い情報がひっかかりやすい)。
numpy.ndarrayクラス
君はPythonにおける「リスト」というオブジェクトを学んだだろう(オブジェクトとは何かわからない人はこちらを読んでみよう)。それはオブジェクトを並べてひとまとまりにするものであり, 例えば
[1, 2, 3]
のようなものだ(これは整数オブジェクトである1と2と3を並べてできたひとつのリストオブジェクト)。
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, 4, 8]) array([ 2.71828183, 7.3890561 , 20.08553692])
となったはずだ。最初のは各要素の2乗, 次のは2の各要素乗, 最後は各要素のexpが計算されている。このような芸当はリストはできないのだ!
このように, np.ndarrayは, 数値の集まり(ベクトルや行列)を表現したり処理するのに便利であり, 大変よく使われる。
[課題9-1] 上のような計算をリストでやろうとしてみよ。つまり, 以下の命令をやってみよ:
[1, 2, 3]**2 (結果はどうなった?) 2**[1, 2, 3] (結果はどうなった?) np.exp([1, 2, 3]) (結果はどうなった?)
いずれもエラーが出るだろう!
等差数列を作る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-2] 初項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-3] 以下の命令は, それぞれ何を作るか?
2**np.arange(0,10) 2**np.arange(0,10)[2:9:3] 3*2**np.arange(0,10)
[課題9-4] 初項8, 公比0.5, 項数10の等比数列をnp.ndarrayで作成せよ。
[よくある質問] Python理解しながらやってはいるもののメソッドとか全然覚えられてないんですが大丈夫なのでしょうか?
... プログラミングで出てくるこまごまとしたこと(モジュールや関数やメソッドの名前など)は覚えようとして覚えるものではありません。使っているうちによく出てくるものは自然に覚えます。まずはそういうのがあると知ること, そして慣れていくことが大事です。
Keyword(s):
References:[python入門]