NumPy:【次元を操作】する方法いろいろ
目次
サマリ
- np.reshape
- 形状変換
- -1は残り全部と言う意味
- np.squeeze
- 次元削除
- .T
- 転置
- 次元を逆に並び替え
- np.transpose
- .Tより柔軟な転置
- 次元を任意に並び替え
- np.newaxis
- 次元を増やす
- 次元追加
- ファンシーインデックス参照を使った並び替え
- 次元並び替え
前提
- np.arange
- np.ndim
- ファンシーインデックス参照
サンプルコード
reshape(形状変換)
基本
import numpy as np
a = np.arange(12).reshape(3,4)
b = a.reshape(2,6)
print(a)
print(a.shape)
print(b)
print(b.shape)
[[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] (3, 4) [[ 0 1 2 3 4 5] [ 6 7 8 9 10 11]] (2, 6)
- 中身のデータより形状の(3,4)や(2,6)に注目する
- (3,4)
- 3×4=12のデータがある
- (2,6)
- 2×6=12のデータになった
- データこの数は変わらず
- 形が2行6列に変化させる
次元数を変更
import numpy as np
a = np.arange(18).reshape(3,6)
b = a.reshape(3,3,2)
print(a)
print(a.shape)
print(b)
print(b.shape)
[[ 0 1 2 3 4 5] [ 6 7 8 9 10 11] [12 13 14 15 16 17]] (3, 6) [[[ 0 1] [ 2 3] [ 4 5]] [[ 6 7] [ 8 9] [10 11]] [[12 13] [14 15] [16 17]]] (3, 3, 2)
- 2次元から3次元に変換することもできる
- (3,6)
- 3×6=18個のデータ
- (3,3,2)
- 3x3x2=18個のデータ
- データの個数が一致していれば2次元から3次元に変換できる
うまく行かないパターン
import numpy as np
a = np.arange(12).reshape(4,3)
print(a.shape)
b = a.reshape(2,2)
(4, 3)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-175-ea6b1b62f1e1> in <module>
2 a = np.arange(12).reshape(4,3)
3 print(a.shape)
----> 4 b = a.reshape(2,2)
ValueError: cannot reshape array of size 12 into shape (2,2)
- (4,3)
- 4×3=12個のデータ
- (2,2)
- 2×2=4個のデータに変換せよと言う指定
- データの個数が一致しないので形状変換(reshape)はエラーになる
- 2×6とか6×2とか3×4とかはOK
次元削除
import numpy as np
a = np.arange(18).reshape(3,3,2)
b = a.reshape(3,-1)
c = a.reshape(-1)
print(a.shape)
print(b.shape)
print(c.shape)
(3, 3, 2) (3, 6) (18,)
- 同様に全体の個数があっているなら次元数を削減(次元削除)できる
- ここでは個数の細かい計算を省ける「-1」を紹介
- 「-1」は残り全部と言う意味
- (3,3,2)
- 3x3x2=18個のデータ
- (3,-1)
- 3x?=18個のデータになるようにうまくやる
- つまり?は6になる
- (3,6)と等価
- (-1)
- この場合は(18)と等価
- 次元削除については次項のnp.squeezeも参照してください
np.squeeze(次元削除)
データ作成
import numpy as np
a = np.array([[2, 3, 2]])
print(a)
print(a.shape)
print(a.ndim)
[[2 3 2]] (1, 3) 2
- [[2, 3, 2]]
- 2次元データになるように[[…]]としています
- 1次元[2,3,2]とデータの中身は同じです
- shapeの結果(1,3)
- 1次元目の要素数が1つになっています
- ndimの結果2
- ndarray(NumPy配列)としては2次元データとなっています
次元削除
b = a.squeeze()
print(b)
print(b.shape)
print(b.ndim)
[2 3 2] (3,) 1
- (1,3)から(3, )に次元削除された
- np.reshapeと違って要素数が1の次元を削除するような次元削除です
- ndimの結果も1で1次元ndarrayになった
- (1, 3)でも(3, )でも入っているデータは{2,3,2}で同じです
- 参考
- (1, 3)と(3, )の違いについては下記の記事で説明しています
.T(転置、次元が逆順になる)
実際の数字で見る
import numpy as np
a = np.random.randint(1,10, (2,3))
b = a.T
print(a)
print(a.shape)
print(b)
print(b.shape)
[[9 7 1] [5 7 3]] (2, 3) [[9 5] [7 7] [1 3]] (3, 2)
各次元の要素数に注目する
import numpy as np
a = np.random.randint(1,10, (2,3,4))
b = a.T
print(a.shape)
print(b.shape)
(2, 3, 4) (4, 3, 2)
- (2,3,4)から(4,3,2)
- 並び順が変わっている
- 転置とは並び順を変えるものと理解できる
- 転置を理解するために
- 3次元以上になると実際のデータがどう入れ替わるかイメージするのは難しい
- 各次元の数字(要素数)に注目すると転置の新しい概念が得られる
np.transpose(転置、次元を任意に並び替え)
データ作成
import numpy as np
a = np.arange(24).reshape(3,4,2)
print(a.shape)
(3, 4, 2)
- 元の(3,4,2)
- 1次元目(0)の要素数が3
- 2次元目(1)の要素数が4
- 3次元目(2)の要素数が2
転置実行
b = a.transpose(1,2,0)
print(b.shape)
(4, 2, 3)
- 前項の「.T」の動作が理解できていれば簡単
- .transposeの引数(1,2,0)
- 1次元目の要素数を「元2次元目(1)の要素数4」に
- 2次元目の要素数を「元3次元目(2)の要素数2」に
- 3次元目の要素数を「元1次元目(0)の要素数3」に
- 結果(4,2,3)になる
- まとめ
- 次元の要素数を任意で並び替えできる
(並び替えなので3x4x2=24個のデータ数は変わらない)
- 並び順を指定できる
(前項の「.T」は逆順にするだけで、指定はできない)
- 次元の要素数を任意で並び替えできる
np.newaxis(次元を増やす)
import numpy as np
a = np.arange(10).reshape(2,5)
b = a[np.newaxis,:,:]
c = a[:,:,np.newaxis]
print(a.shape)
print(b.shape)
print(c.shape)
(2, 5) (1, 2, 5) (2, 5, 1)
- b
- 先頭に新しい次元が加わっている
- c
- 末尾に新しい次元が加わっている
- 参考
- どんな場合に役に立つかは(2, )と(1,2)の違いを理解することが近道
- (2, )と(1,2)の違いの説明した下記記事にヒントあり
ファンシーインデックス参照による次元並び替え
データ作成
import numpy as np
a = np.arange(18).reshape(3,6)
print(a)
print(a.shape)
[[ 0 1 2 3 4 5] [ 6 7 8 9 10 11] [12 13 14 15 16 17]] (3, 6)
- 形状(3,6)のndarray(NumPy配列)を作成
- np.arangeを利用したので、各行の数字がキレイに並んでいるます
- 一番右の列を移動させるので注目
b = a[:, [0, 5, 1, 2, 3, 4]]
print(b)
print(b.shape)
[[ 0 5 1 2 3 4] [ 6 11 7 8 9 10] [12 17 13 14 15 16]] (3, 6)
- [0,5,1,2,3,4]
- ここで指定している数字は列番号(0から始まる)
- 5(6列目)を2列目に移動すると言う指定
- 転置と比較して理解を深めてください
- 転置は次元を並び替え
- この例では列を並び替え
- 両者をきっちり理解することで、次元に対する理解度がUPします


