数値計算モジュール NumPy
配列の生成と基本的な操作 モジュールの読み込み NumPyのモジュールを読み込む import numpy NumPyのモジュールをnpという名前をつけて読み込む import numpy as np Numpyのモジュールをすべて読み込む from numpy import *
配列の生成と基本的な操作 リスト、タプルからの変換(1) リスト、タプルから変換して配列を生成するには numpy.array(リストやタプルなど) を用いる。
配列の生成と基本的な操作 リスト、タプルからの変換(2) a = np.array([1 ,2 ,3 ,4.0]) print( ’a =’ ,a ) >>> a = [ 1., 2., 3., 4. ] intとfloatが混在しているリストやタプルは値がfloatに統一される [1, 2, 3, 4.0] 配列 1.0 2.0 3.0 4.0
配列の生成と基本的な操作 リスト、タプルからの変換(3) リスト内に含まれるリストの型が違うため2次元配列にならない b = np.array([[ 1 , 2 , 3 ] , [ 4 , 5 . 0 ]]) print( ’b =’ ,b ) >>> b = [[1 , 2 , 3], [4 , 5 . 0 ] ] [[1, 2, 3], [4, 5.0] ] [1, 2, 3] (4, 5.0)
配列の生成と基本的な操作 リスト、タプルからの変換(4) [[1, 2, 3], [4, 5, 6], (7, 8, 9.0)] リストとタプルが混在していても型が同じなため2次元の配列となる d = np.array([[1, 2, 3] ,[4, 5, 6] ,(7, 8, 9.0)]) print(’d =’,d) >>> d = [[ 1. ,2. ,3.], [ 4., 5., 6.], [ 7., 8., 9.]] 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0
配列の生成と基本的な操作 リスト、タプルからの変換(5) numpy.array(リストやタプルなど, dtype) dtypeによりint(整数型)、float(浮動小数点数型)、complex(複素数型)を指定できる f = np.array([[1 ,2 ,3] ,[4 ,5 ,6]] ,dtype=complex) print (’ f =’ , f) >>> f = [[ 1.+0.j, 2.+0.j, 3.+0.j ], [ 4.+0.j, 5.+0.j, 6.+0.j ]]
配列の生成と基本的な操作 多次元配列の情報(1) 配列の次元数 ndarray.ndim 配列の型 (返り値は整数のタプル) ndarray.shape 配列の要素数 ndarray.size
配列の生成と基本的な操作 多次元配列の情報(2) a1 = np.array([0 ,1 ,2 ,3]) print(’a1 = ’, a1) print(’ndim : ’ ,a1.ndim) print(’shape : ’,a1.shape) print(’size : ’,a1.size) >>> a1 = [0, 1, 2, 3] ndim : 1 shape : (4 ,) size : 4 a1 1 2 3 a1は1次元配列 型は(4,) サイズは4
配列の生成と基本的な操作 多次元配列の情報(3) 配列のサイズが変化しなければ ndarray.shapeで型を直接変更できる a =np.array([[1, 2], [3, 4]]) print(’a = ’, a) >>> a = [[1, 2], [3, 4]] a.shape = (4 ,) a = [1, 2, 3, 4] 1 2 3 4 2×2の配列から 1×4の配列に 1 2 3 4
配列の生成と基本的な操作 備え付けの生成関数(1) 指定された型で成分がすべて0の配列を返す関数 np.zeros(配列の型, dtype) #配列の型はタプルで指定する 指定された配列と同じ型で成分がすべて0の配列を返 す関数 np.zeros_like(配列,dtype) →0ベクトルや0行列として利用できる
配列の生成と基本的な操作 備え付けの生成関数(2) 指定された型で成分がすべて1の配列を返す関数 np.ones(配列の型, dtype) #配列の型はタプルで指定する 指定された配列と同じ型で成分がすべて1の配列 を返す関数 np.ones_like(配列,dtype)
配列の生成と基本的な操作 備え付けの生成関数(3) 指定された型ですべて指定された値を成分に持 つ配列を返す関数 np.full(配列の型, 指定する値,dtype) 指定された配列と同じ型ですべて指定された値を 成分に持つ配列を返す関数 np.full_like(配列,指定する値, dtype)
配列の生成と基本的な操作 備え付けの生成関数(4) ある区間を指定された間隔に区切った値を成 分とした配列を生成する関数 np.arange(start, stop, step, dtype) startの既定値は0、stepの既定値は1 startからstopまでの区間をstep間隔に区切っ た値を配列とする。 np.array(range(n)) と np.arange(n)では 引数が正整数nのとき同じ結果を得るが np.arange(n)の方が速い
配列の生成と基本的な操作 備え付けの生成関数(5) ある区間を指定された値に等分した点のを成分と した配列を生成する関数 np.linspace(start,stop,num=50,endpoint=True, dtype=None) startからstopまでの区間をnum等分にした点の値 を配列とする。 arangeとlinspaceでは似たようなことができるが、引 数stepが整数でない場合はデータに不整合を生じ る場合があり、linspaceを使ったほうがよい。
配列の生成と基本的な操作 備え付けの生成関数(6) 成分の値の対数が等間隔になる配列を生成する関数 np.logspace(start,stop,num=50,endpoint=True, base=10.0, dtype=None) baseのstart乗からbaseのend乗までの値を、baseを底 とする対数をとるとnum等分された点の値を配列とす る。 endpointをFalseにすると配列の最後の値となるbase のstop乗を除外できる。
配列の生成と基本的な操作 乱数による配列の生成(1) NumPyには擬似乱数を生成するサブモジュール randomが備わっている。 import numpy.random as random などをしてインポートすれば使用可能。
配列の生成と基本的な操作 乱数による配列の生成(2) 擬似乱数の系列の初期化 random.seed(seed値) 指定した区間の一様乱数を生成する random.uniform(下限,上限, size=None) 指定した区間で整数値をとる一様乱数を生成する random.randint(下限,上限,size=None) #sizeで配列の型を指定すると乱数を値とした配列を 持つ # 区間は[下限,上限)
配列の生成と基本的な操作 乱数による配列の生成(3) 平均0分散1の標準正規分布に従う乱数を成分とする 指定した型の配列を生成する random.randn(配列の型) 与えられた配列などをランダムな順列にして生成する random.permutation(配列or整数) #整数を指定した場合はnp.arange(整数)が代入される
配列の生成と基本的な操作 乱数による配列の生成(4) 1次元配列のランダムサンプリングを生成する random.choice(1次元配列or整数, size=None,replace=True) #整数を指定した場合はnp.arange(整数)が代入される #sizeはサンプルの個数か配列の型 #replaceは値の重複を許す場合はTrue #pは1次元配列と同じ長さの配列でそれぞれの 成分がサンプリングされる確率を指定できる
配列の生成と基本的な操作 配列データの参照,基本操作(1) 生成した配列データはPython標準のリストと同様 に,添え字(index;インデックス)によって参照する ことができる a = np.arange(10) print ( ’a = ’ , a ) >>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] a[−3] = 100 print( ’a = ’ ,a) a = [ 0, 1, 2, 3, 4, 5, 6, 100, 8, 9] 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 -3 -2 -1 1 2 3 4 5 6 100 8 9 1 2 3 4 5 6 7 8 9 -3 -2 -1
配列の生成と基本的な操作 配列データの参照,基本操作(2) 2次元の配列データは2つの添え字で参照する b = np.array ([[1 ,2 ,3 ,4] ,[5 ,6 ,7 ,8] ,[9 ,10 ,11 ,12]]) print ( ’b = ’ , b ) >>> b = [ [ 1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11, 12]] b[0 ,−1] , b[2 ,−2] = b[2 ,−2] , b[0 ,−1] print ( ’b = ’ ,b) b = [ [ 1, 2, 3, 11], [ 9, 10, 4, 12]] -3 1 -2 2 -1 3 1 2 3 4 5 6 7 8 9 10 11 12 -2 1 -1 2 -3 1 -2 2 -1 3 -2 1 -1 2 1 2 3 11 5 6 7 8 9 10 4 12
配列の生成と基本的な操作 配列データの参照,基本操作(3) リストと同様に’:’を用いてスライス表記が可能 aを配列とするとa[i:j:k]は,第i番目の要素から j-1 番目 の要素まで,k-1飛ばしの部分配列という意味になる。 ただしi,j,kともに省略可能で,iの既定値は0。Jの既定 値はnp.alen(a)つまりaの0軸に沿った長さ,kの既定値 は1である。 a = np.arange(10) b = −np.arange(5) a [0: 10:2] = b print (a) >>> a = [ 0, 1, −1, 3, −2, 5, −3, 7, −4, 9] 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 -1 -2 -3 -4 1 2 3 4 5 1 -1 3 -2 5 -3 7 -4 9 1 2 3 4 5 6 7 8 9
配列の生成と基本的な操作 配列データの参照,基本操作(4) aを1 次元配列とするとa[::-1]は配列aの要素を 逆順に並べた配列となる a = np.arange(10) print( ’a = ’ ,a) >>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] a_rev = a [:: −1] print ( ’ a rev = ’ , a rev ) a_rev = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 1 2 3 4 5 6 7 8 9 -10 1 -9 2 -8 3 -7 4 -6 5 -5 6 -4 7 -3 8 -2 9 -1 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9
配列の生成と基本的な操作 配列データの参照,基本操作(5) bを2次元配列とすると、b[2,:]はbの2行目,b[:,3]はb の3列目をそれぞれ配列としたものを表す b = np.arange(12).reshape(3 ,4) b2 = b[2 , :] b3 = b[: , 3] print(’b2 = ’, b2) print(’b3 = ’ ,b3) >>> b2 = [ 8 9 10 11] b3 = [ 3 7 11] 1 2 3 1 2 3 4 5 6 7 8 9 10 11 1 2
配列の生成と基本的な操作 配列データの参照,基本操作(6) NumPyの多次元配列ndarrayは,配列の要素数を 変えなければ, reshapeメソッドを使う方法で,その 中身のデータを変更せずに自在に型を変えること ができる。 a = np.arange(15) a.shape = (3 ,5) b = a.reshape((5 ,3)) >>> b = [ [ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11], [12, 13, 14]] a 1 2 3 4 5 6 7 8 9 10 11 12 13 14 shape b 1 2 3 4 5 6 7 8 9 10 11 12 13 14 a 1 2 3 4 5 6 7 8 9 10 11 12 13 14 reshape
配列の生成と基本的な操作 配列データの参照,基本操作(7) reshapeメソッドの引数には変形後の型を渡すが,そ こで-1が使われている場合,配列のサイズ(変更しな い)と配列の次元が考慮され,それに合うように型が 自動的に決められる。 a = np.arange(12).reshape(3 ,4) b = a.reshape((−1 ,6)) print( ’b = ’ , b) >>> b = [ [ 0, 1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10, 11]] b = a.reshape(−1) b = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] a 1 2 3 4 5 6 7 8 9 10 11 b 1 2 3 4 5 6 7 8 9 10 11 b 1 2 3 4 5 6 7 8 9 10 11
配列の生成と基本的な操作 配列データの参照,基本操作(8) 多次元配列ndarrayクラスには,np.newaxis(新しい軸) がある。付け加えるとで配列に新しい軸が加わり次元 が増える。ただし新しい軸方向の広がりは1である。 a = np.arange(5) a = a[np.newaxis,:,np.newaxis] print( ’a =’ , a) >>> a = [ [ [ 0 ], [1], [2], [3], [4] ] ] 1 2 3 4 1 2 3 4 ↙と↑方向に次元が広がっている
配列の生成と基本的な操作 配列データの参照,基本操作(9) 新たに軸を加えるのとは逆の操作をするのが ravelである。ndarray.ravel()で,配列aの余分な 軸を取り除き1次元の配列にする。a.reshape(- 1) と等価である。 a = np.arange(12).reshape((3 ,4)) print(’a.ravel =’, a.ravel()) print(’a.reshape(−1) =’, a.reshape(−1)) >>> a.ravel = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] a.reshape(−1) = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] 1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11
配列の生成と基本的な操作 ブロードキャスト(1) ブロードキャスト(broadcast)機能とは,型の異なる配列同士の演 算を行うための機能 NumPyでの配列を用いた演算の基本のルールは成分ごとである a = np.arange(12).reshape((3 ,4)) b = np.arange(12).reshape((3 ,4)) print( ’a∗b=’ ,a∗b) >>> a∗b= [ [ 0, 1, 4, 9], [ 16, 25, 36, 49], [ 64, 81, 100, 121]] a b 1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11 1 4 9 16 25 36 49 64 81 100 121
配列の生成と基本的な操作 ブロードキャスト(2) スカラーと配列の演算の場合、スカラーと 配列の成分の演算結果を成分とした同じ 型の配列となる。 a = np.arange(12).reshape((3 ,4)) b = a∗2 print( ’b=’ ,b) >>> b= [ [ 0, 2, 4, 6], [ 8, 10, 12, 14], [ 16, 18, 20, 22]] a 1 2 3 4 5 6 7 8 9 10 11 ×2 2 4 6 8 10 12 14 16 18 100 121
配列の生成と基本的な操作 ブロードキャスト(3) ここまでは型の同じ配列の演算だが型の異なる 配列同士の演算はどうなるか 2つの配列に対しブロードキャスト可能であれば 演算を行う ブロードキャストの可否はNumPyが自動で調べる ため、実際にチェックをする必要はない
配列の生成と基本的な操作 ブロードキャスト(4) 実際の演算の様子 a = np.arange(12).reshape((3 ,1 ,4)) b = np.array([0 ,100 ,1000]).reshape((1 ,3 ,1)) print ( ’a+b=’ ,a+b) >>> a+b= [ [ [ 0 1 2 3] [ 100 101 102 103] [1000 1001 1002 1003]] [ [ 4 5 6 7] [ 104 105 106 107] [1004 1005 1006 1007]] [ [ 8 9 10 11] [ 108 109 110 111] [1008 1009 1010 1011]]] 3 7 11 2 6 10 1 5 9 4 8 100 1000 3 7 11 2 6 10 1 5 9 4 8 1003 1007 1011 1002 1006 1010 1001 1005 1009 1000 1004 1008
Numpyの関数(1) NumPyでは次の数学関数が用意されている 円周率 π numpy.pi(= 3.141592653589793) 円周率 π numpy.pi(= 3.141592653589793) Napier数 e numpy.e(= 2.718281828459045) Eulerのγ numpy.euler_gamma(= 0.5772156649015329)
Numpyの関数(2) 配列(行列,ベクトル)の演算: 配列a,b(行列,ベクトル)の演算,和,差,積,商 はそれぞれ,a+b,a-b,a*b,a/bである。 配列 a,bの型が同じならば成分ごとに,異なれば ブロードキャスト演算が行われる。
Numpyの関数(3) 配列のドット積演算: dot(a,b)は配列 a,b のドット積を返す a,b が1次元配列(ベクトル)の場合は内積を返す a,bが2次元配列(行列)の場合は行列の積を返す
Numpyの関数(4) 行列の積: Python3.5から行列(2次元配列)の積を記号@で計算 できるようになった 42 48 54 114 A = np.arange(12).reshape((3 ,4)) B = np.arange(12).reshape((4 ,3)) print( ’AB by dot =’ , np.dot (A,B)) print( ’AB by @ = ’ , A @ B) >>> AB by dot = [ [ 42 48 54] [114 136 158] [186 224 262]] AB by @ = [ [ 42 48 54] A B 1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11 42 48 54 114 136 158 186 224 262