多次元配列の操作

目的

これまでにnumpyモジュールのndarrayオブジェクトを使用した多次元配列の作り方を学んだ.ここでは,多次元配列に対する簡単な処理を学ぶ.

説明

2次元配列の要素の値の和を求める処理を考えよう.

numpyモジュールの関数を使用する方法

2次元配列の要素の値の和を求めるには以下のようにすればよい.

8行目のように,numpyモジュールのsum関数を2次元配列を引数に指定して呼び出すと,2次元配列の要素の値の和が返される.また,9行目のように,キーワード引数axisに0を指定すると,外側の軸方向に対する要素の値の和が返され,10行目のように,キーワード引数axisに1を指定すると,内側の軸方向に対する要素の値の和が返される.

配列オブジェクトのメソッドを使用する方法

2次元配列の要素の値の和は,配列オブジェクトのsumメソッドを使用しても求められる.

8行目から10行目のように,配列オブジェクトのsumメソッドを呼び出しても,要素の値の和を求めることができる.

条件を満たす配列の要素数をカウント

配列の和を求める処理は,条件を満たす配列の要素数を求める際に使用できる.

8行目のように,配列に対して比較演算子を用いて条件を記述すると,条件を満たす要素はTrue,満たさない要素はFalseとなる配列が返された.Trueは1ビットの整数で1,Falseは0と解釈できるため,10行目や13行目のようにsum関数やsumメソッドにより和を求めることで,条件を満たす配列の要素数を求めることができる.

最小値・最大値

2次元配列の要素の値の最小値・最大値を求める処理を考えよう.

numpyモジュールの関数を使用する方法

2次元配列の要素の値の最小値・最大値を求めるには以下のようにすればよい.

8行目から14行目のようにnumpyモジュールのamin関数・amax関数を使用すると,要素の値の最小値・最大値を求めることができる.また.16行目から22行目のように,argmin関数・argmax関数を使用すると,最小値・最大値の要素のインデックス番号を求めることができる.

配列オブジェクトのメソッドを使用する方法

2次元配列の要素の値の最小値・最大値は,配列オブジェクトのメソッドを使用しても求められる.

8行目から14行目のように,配列オブジェクトのminメソッド・maxメソッドを使用しても最小値・最大値を求めることができ,16行目から22行目のように,argminメソッド・argmaxメソッドを使用して最小値・最大値の要素のインデックス番号を求めることができる.

1次統計量

2次元配列の要素の値から,平均や分散等の1次統計量を求めてみよう.

numpyモジュールの関数を使用する方法

2次元配列の要素の値から平均・中央値・標準偏差・分散を求めるには,以下のようにすればよい.

7行目で,平均67.3・標準偏差9.2の正規分布からランダムに900個の整数値を生成し,300人の3教科のテストの点数からなる2次元配列scoresを作っている.

10行目のように,numpyモジュールのaverage関数を2次元配列を引数として指定して呼び出すと,全体の平均点が返される.11行目のようにmean関数を使用しても全体の平均点を求めることができる.12行目のようにmedian関数を使用すると中央値を,13行目のようにstd関数を使用すると標準偏差(standard deviation)を,14行目のようにvar関数を使用すると分散(variance)を求めることができる.

また,17行目から21行目のように,キーワード引数axisに0を指定することで,3教科それぞれの平均・中央値・標準偏差・分散を求めることができる.

配列オブジェクトのメソッドを使用する方法

配列オブジェクトのメソッドを使用しても,平均・標準偏差・分散を求めることができる.

10行目のように,配列オブジェクトのmeanメソッドを呼び出すと,要素の値の平均を求めることができる.11行目のようにstdメソッドを呼び出すと標準偏差を,12行目のようにvarメソッドを呼び出すと分散を求めることができる.

また,15行目から17行目のように,キーワード引数axisに0を指定すると,3教科それぞれの平均・標準偏差・分散を求めることができる.

繰り返しによる全要素の参照

2次元配列の全要素を1次元配列のときと同様に繰り返しを使用して参照してみよう.

7,8行目のように繰り返しを使用して2次元配列の要素を表示すると,以下のように表示され,2次元配列の行が表示されていることがわかる.これは,多次元配列にfor文を使用すると,一番外側の軸方向に繰り返されるためである.

繰り返しにより2次元配列の全要素を参照するには,以下のように2重の繰り返しを行えばよい.

7行目のように外側の軸方向に繰り返しを行い,そのそれぞれに対して,8行目のように内側の軸方向に繰り返しを行えば,以下のように,2次元配列の全要素を参照することができる.

また,以下のように2次元配列を平坦化すると,1重の繰り返しで全要素を参照することができる.

7行目で,2次元配列オブジェクトのravelメソッドにより平坦化を行い,1次元配列に対して繰り返しを行っている.このようにしても2次元配列の全要素を参照することができる.

配列の結合

2つの2次元配列を結合するにはnumpyモジュールのconcatenate関数を使用すればよい.

6,7行目のように,numpyモジュールのconcatenate関数を,結合したい2つの配列からなるタプルと結合する軸方向を指定して呼び出すと,結合された配列が返される.axisを0として指定した場合には,外側の軸方向に,1として指定した場合には,内側の軸方向に配列が結合される.

また,14,15行目のように,元の配列のある要素を書き換えても,結合した配列の要素は変更されておらず,これらは別のオブジェクトであることが確認できる.

配列の分割

等間隔で分割

配列を分割する方法を確認しよう.

6,7行目のように,numpyモジュールのsplit関数を,分割したい配列と分割数と分割する軸方向を指定して呼び出すと,分割された配列のリストが返される.6行目では外側の軸方向に2分割し,7行目では内側の軸方向に2分割している.

また,17行目のように元の配列のある要素の値を変更すると,分割した配列の要素の値も変更されており,これらは同じオブジェクトを指していることがわかる.

例えば以下のように,(3,3)のshapeの2次元配列を外側の軸方向に2分割しようとすると,

等分できないため,「ValueError: array split does not result in an equal division」というエラーメッセージが表示される.

指定した位置で分割

numpyモジュールのsplit関数は,第2引数にインデックス番号のリストを指定することで,指定した位置で配列を分割できる.

6,7行目のように,第2引数に[1,2]と指定すると,インデックス番号が1の位置の手前と2の位置の手前で配列が3つに分割される.このプログラムを実行すると,以下のように指定した位置で配列が分割されていることがわかる.

おおよそ等間隔に分割

配列をおおよそ等間隔に分割するには,numpyモジュールのarray_split関数を使用すればよい.

6行目のように,(5,5)のshapeの配列を外側の軸方向に2分割すると,3行と2行の2つの配列に(おおよそ等間隔に)分割される.7行目のように記述すると,3列と2列の2つの配列に分割される.

また,14行目のように,元の配列のある要素の値を変更すると,分割後の配列の要素の値も変更されていることから,これらは同じオブジェクトを指していることがわかる.

軸の入れ替え

多次元配列の軸の順番を入れ替えるには,以下のようにすればよい.

5行目で(3,4,2)のshapeの3次元配列arrayを作成している.6,7行目のように,numpyモジュールのtranspose関数を,3次元配列arrayと入れ替え後の軸のインデックス番号からなるタプルを引数に指定して呼び出すと,軸の順番が入れ替わった配列が返される.6行目では,(1, 2, 0)と指定しているため,元のインデックス番号1の軸が最初に,元のインデックス番号2の軸が2番目に,元のインデックス番号0の軸が最後に変更される.7行目では,(2, 0, 1)と指定しているため,元の最後の軸が最初に,元の最初の軸が中央に,元の中央の軸が最後に変更される.

また,15行目のように,元の配列のある要素の値を変更すると,軸の順番を入れ替えた配列の要素の値も変更されていることから,これらは同じオブジェクトを指していることがわかる.

課題

課題0

300人の5科目のテストの点数の配列を作り,各科目で最も良かった点数と最も悪かった点数の差を求めよ.

課題1

300人の5科目のテストの点数の配列を作り,各科目で最も点数が良かった学生との最も点数が悪かった学生の番号を表示せよ.

課題2

300人の5科目のテストの点数の配列を作り,5科目の平均点が最も良かった学生と最も悪かった学生の番号を表示せよ.

課題3

300人の5科目のテストの点数の配列を作り,各科目の平均点と中央値と標準偏差を求めよ.

課題4

300人の3科目のテストの点数の配列と300人の2科目のテストの点数の配列を作り,結合して300人の5科目のテストの点数の配列を作れ.

課題5

100人の5科目のテストの点数の配列と80人の5科目のテストの点数の配列と120人の5科目のテストの点数の配列を作り,結合して300人の5科目のテストの点数の配列を作れ.

課題6

300人の5科目のテストの点数の配列を作り,100人ずつ3クラスに分割せよ.

課題7

300人の5科目のテストの点数の配列を作り,100人・80人・120人の3クラスに分割せよ.

課題8

300人の5科目のテストの点数の配列を作り,5科目を3科目と2科目に分割せよ.

課題9

shapeが(300, 10, 5)である300人の10回分の5科目のテストの点数の配列を作り,軸を入れ替えshapeが(5, 300, 10)となるようにせよ.