今回は、NumPyの配列の次元を変換する方法について。
1次元の配列を多次元の配列に変換する方法と、多次元の配列を1次元の配列に変換する方法を学ぶ。
まずは1次元の配列を多次元の配列に変換する方法から。
1次元 → 多次元
1次元の配列を多次元の配列に変換するには、reshape()を使う。reshape()には、関数として使う方法とndarrayのメソッドとして使う方法がある。
関数のreshape
reshape関数の書式は以下の通り。numpy.reshape(a, newshape, order='C')
aは変換する配列、newshapeは変換後の配列の形を指定する。
orderは、変換後のデータの並び順を指定する。'C'を指定するとC言語のように処理を行い、行方向優先となる。'F'を指定するとFortranのように処理を行い、列方向優先となる。
orderを指定しない場合は、デフォルトでorder='C'となる。
以下は、arangeで要素数6(0〜5)の配列を作り、reshapeを使って2行3列の2次元配列に変換する例。
(例)orderを指定しない場合
import numpy as np
arr = np.arange(6)
arr = np.reshape(arr, (2,3))
print(arr)
#結果
[[0 1 2]
[3 4 5]]
(例)order='F'とした場合
import numpy as np
arr = np.arange(6)
arr = np.reshape(arr, (2,3),order='F')
print(arr)
#結果
[[0 2 4]
[1 3 5]]
メソッドのreshape
NumPyの配列であるndarrayのメソッドとしてreshapeを使う場合、1つ目の引数に変更する配列を指定する必要はない。reshapeメソッドの書式は以下の通り。
ndarray.reshape(shape, order='C')
メソッドの場合もデフォルトではorder='C'となっている。
import numpy as np
arr = np.arange(6)
print(arr.reshape((2,3)))
#結果
[[0 1 2]
[3 4 5]]
多次元→1次元
多次元から1次元の配列に変換する時もreshapeを使うことができる。
しかし、もっと有効な方法もある。まずはreshapeでの変換を試し、その後ほかの方法を試すことにする。
reshapeを使う方法
多次元から1次元に変換する時も、基本的な使いかたは1次元から多次元に変換する時と同じ。違う点は、引数shapeに変換後の形をタプルで指定していた点を、変換後の1次元配列の要素数を数値で指定するという点。
以下は、2行3列の2次元配列をreshapeを使って1次元配列に変換する例。
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
b = a.reshape(6)
print(b)
#結果
[1 2 3 4 5 6]
上記の例では、変換前の2次元配列の要素数が6なので、reshapeの引数で指定する変換後の1次元配列の要素数にも6を指定している。
reshapeの引数に6以外の値を指定するとValueErrorが発生してしまうので注意が必要。
flattenとravel
flattenとravelは、どちらも多次元の配列を1次元の配列に変換することができる。引数に変換後の1次元配列の要素数を指定する必要がないのでreshapeより使いやすい。
flattenとravelの違いは、flattenは新しくメモリを確保しコピーを作成するが、ravelはコピーを作成しないということ。
以外で具体例を示す。
flattenの使用例
import numpy as np
#①
d2 = np.array([[1,2,3],[4,5,6]])
print('d2:' + str(d2))
print('-' *30)
#②
d1 = d2.flatten()
print('d1:' + str(d1))
print('-' *30)
#③
d1[0] = 100
print('d1:' + str(d1))
print('-' *30)
#④
print('d2:' + str(d2))
#結果
d2:[[1 2 3]
[4 5 6]]
------------------------------
d1:[1 2 3 4 5 6]
------------------------------
d1:[100 2 3 4 5 6]
------------------------------
d2:[[1 2 3]
[4 5 6]]
【解説】
①で2行3列の2次元配列を作り、変数d2に代入する。
②でflattenを使ってd2を1次元配列にしてd1に代入
③でd1の1つ目の要素を100に変更
④で元の2次元配列(d2)を表示
③でd1を変更しても、元の2次元配列(d2)は何も変更されていない。
ravelの使用例
import numpy as np
#①
d2 = np.array([[1,2,3],[4,5,6]])
print('d2:' + str(d2))
print('-' *30)
#②
d1 = d2.ravel()
print('d1:' + str(d1))
print('-' *30)
#③
d1[0] = 100
print('d1:' + str(d1))
print('-' *30)
#④
print('d2:' + str(d2))
#結果
d2:[[1 2 3]
[4 5 6]]
------------------------------
d1:[1 2 3 4 5 6]
------------------------------
d1:[100 2 3 4 5 6]
------------------------------
d2:[[100 2 3]
[ 4 5 6]]
【解説】
①で2行3列の2次元配列を作り、変数d2に代入する。
②でravelを使ってd2を1次元配列にしてd1に代入
③でd1の1つ目の要素を100に変更
④で元の2次元配列(d2)を表示
flattenを使った時とは異なり、次元変換後の変更(③)が変更前の配列にも適用されていることが分かる。(④)
flattenとravelの使い分け
変更前の配列を保持しておきたい時はflattenを使うことになる。しかし、flattenはコピーを生成するために新たにメモリを確保するので、パフォーマンス的にはravelに劣る。
そのため、コピーが必要ない場合、特に大きなデータを扱う時はravelを使うことでパフォーマンス向上を期待できる。
以上
NumPyの配列の次元の変換方法について
0 件のコメント :
コメントを投稿