NumPy3 軸・形状変更

NumPyの第3回目となります。

Aidemyさんの講座を受講しながらアウトプットのためにブログを更新しております。

AidemyさんHP → https:// aidemy.net

今回は軸の入替や形状変更をトピックスとしていきます。

その前に軸の説明をしておきます。

【Numpyにおける軸の理解】

Numpyにおける軸とは、配列内の数値が並ぶ方向のことです。

2次元配列には2つ、3次元配列には3つ、軸があることになります。

import numpy as np 
a = np.array([[9,8,7],[6,5,4]]) 
print(a)

>>> 出力結果
[[9 8 7]
[6 5 4]]

これは2次元配列です。

2次元配列の場合、axis=0 が縦方向を表し、axis=1 が横方向を意味します。

画像1


import numpy as np
b = np.array([[[100,101,102,103],[104,105,106,107],[108,109,110,111]],
                     [[112,113,114,115],[116,117,118,119],[120,121,122,123]]])
print(b)

>>> 出力結果
[[[100 101 102 103]
 [104 105 106 107]
 [108 109 110 111]]
[[112 113 114 115]
 [116 117 118 119]
 [120 121 122 123]]]

これは3次元配列です。

3次元配列の場合、axis=0 が奥行きaxis=1 が縦方向axis=2 が横方向

画像2

イメージを付けたところで具体的な説明に移ります。

【次元配列の軸の入れ替え(転置)】

2次元のNumPy配列の行と列を入れ替えることを「転置」といいます。
転置を行うには、NumPy配列に続けて.Tと記述します。

例文

import numpy as np

list_1 = [[1,2],[3,4],[5,6]]
arr_1 = np.array(list_1)

print('転置前のarr_1')
print(arr_1)
print('転置後のarr_1')
print(arr_1.T)  #転置


>>> 出力結果
転置前のarr_1   #3行2列のNumPy配列
[[1 2]
[3 4]
[5 6]]
転置後のarr_1  #転置後は2行3列のNumPy配列    #行と列が入れ替わっている
[[1 3 5]
[2 4 6]]


より一般的には、NumPy配列の「軸」の順番を反転させるとも言えます。

【3次元以上の配列の軸の入れ替え】

3次元以上のNumPy配列の軸の順番は、transpose()メソッドで変更します。引数には、新しい軸の順番を指定します。

例えば、引数に(2, 0, 1)を指定した場合、次の変換が行われます。
・元の配列の第2軸を、新しい配列の第0軸にする
・元の配列の第0軸を、新しい配列の第1軸にする
・元の配列の第1軸を、新しい配列の第2軸にする

もう一度、3次元の配列を確認しましょう。

transpose(0,1,2)をイメージしながら、、、

画像3

import numpy as np

list_1 = [[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]]]

arr_1 = np.array(list_1)

print('軸の入れ替え前 shape: ', arr_1.shape)   # shape:  (2, 3, 2)
print(arr_1)

arr_2 = arr_1.transpose(1, 0, 2)      #1軸→0軸へ/0軸が1軸へ/2軸が2軸へ
 
print('arr_2.shape: ', arr_2.shape)   # shape:  (3, 2, 2)
print(arr_2)

arr_3 = arr_1.transpose(2, 0, 1)      #2軸→0軸へ/0軸が1軸へ/1軸が2軸へ 

print('arr_3.shape: ', arr_3.shape)   # shape:  (2, 2, 3)
print(arr_3)


>>> 出力結果
軸の入れ替え前 shape:  (2, 3, 2)  #まずは大きい[ ]で2つ分かれ、次の[ ]で3つに分かれ、[ ]内で2つ
[[[ 1  2]
 [ 3  4]
 [ 5  6]]
[[ 7  8]
 [ 9 10]
 [11 12]]]
arr_2.shape:  (3, 2, 2)  #まずは大きい[ ]で3つ分かれ、次の[ ]で2つに分かれ、[ ]内で2つ
[[[ 1  2]
 [ 7  8]]
[[ 3  4]
 [ 9 10]]
[[ 5  6]
 [11 12]]]
arr_3.shape:  (2, 2, 3)  #まずは大きい[ ]で2つ分かれ、次の[ ]で2つに分かれ、[ ]内で3つ
[[[ 1  3  5]
 [ 7  9 11]]
[[ 2  4  6]
 [ 8 10 12]]]

考え方としては、

①shapeでどのように出力されるかイメージ
②transposeでどのような指示が出されているか理解
③どのように入れ替わるのかイメージ

で考えると少しクリアになるかと思います。

もう一コード。その前にもう一度、、、

例えば、引数に(2, 0, 1)を指定した場合、次の変換が行われます。
・元の配列の第2軸を、新しい配列の第0軸にする
・元の配列の第0軸を、新しい配列の第1軸にする
・元の配列の第1軸を、新しい配列の第2軸にする

画像4

import numpy as np

list_1 = [[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]]]

arr_1 = np.array(list_1)
# 1. transpose()メソッドを利用してarr_1を変形し、arr_2に代入しましょう
arr_2 = arr_1.transpose(2,1,0)

print("変形前")
print(arr_1)

print('1. ')
print(arr_2)

# 2. transpose()メソッドを利用してarr_1を変形し、arr_3に代入しましょう
arr_3 = arr_1.transpose(1,2,0)
print('2. ')
print(arr_3)



>>> 出力結果

変形前
[[[ 1  2]
 [ 3  4]
 [ 5  6]]

[[ 7  8]
 [ 9 10]
 [11 12]]]
1. 
[[[ 1  7]
 [ 3  9]
 [ 5 11]]

[[ 2  8]
 [ 4 10]
 [ 6 12]]]
2. 
[[[ 1  7]
 [ 2  8]]

[[ 3  9]
 [ 4 10]]

[[ 5 11]
 [ 6 12]]]

【配列の形状変更-reshape-】

reshape()メソッドを用いると、NumPy配列のshapeを変更できます。
引数には、shape変更後の各次元の要素数を、降順に指定します。

import numpy as np

# 50個の要素を持つ1次元配列arr_1を作成
arr_1 = np.array(range(50))

print('arr_1 shape: ', arr_1.shape)
print(arr_1)

# reshape()メソッドを用いて、shapeを変える
arr_2 = arr_1.reshape(2, 5, 5)

print('arr_2 shape: ', arr_2.shape)
print(arr_2)


>>> 出力結果
arr_1 shape:  (50,)
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
48 49]

arr_2 shape:  (2, 5, 5)
[[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]
 [20 21 22 23 24]]
[[25 26 27 28 29]
 [30 31 32 33 34]
 [35 36 37 38 39]
 [40 41 42 43 44]
 [45 46 47 48 49]]]

引数の1つを-1と記述すると、他の次元の要素数から値が推測されます。次の例のように、与えられるNumPy配列の要素数が不明な場合などに便利です。

arr_1 = np.array(range(np.random.randint(1, 30))) # ランダムな要素数を持つ配列arr_1
arr_2 = arr_1.reshape(-1, 1) # 行数は不明だが、1列の配列に変形 
print(arr_2)



>>> 出力結果
[[ 0]
[ 1]
[ 2]
[ 3]
[ 4]
[ 5]
[ 6]
[ 7]
[ 8]
[ 9]
[10]
[11]
[12]
[13]
[14]]

【配列の形状変更-resize-】

resize()メソッドを用いると、NumPy配列のshapeを変更できます。

import numpy as np
arr_1 = np.array(range(50))
arr_1.resize(10, 10)
print(arr_1)


>>> 出力結果
[[ 0  1  2  3  4  5  6  7  8  9]
[10 11 12 13 14 15 16 17 18 19]
[20 21 22 23 24 25 26 27 28 29]
[30 31 32 33 34 35 36 37 38 39]
[40 41 42 43 44 45 46 47 48 49]
[ 0  0  0  0  0  0  0  0  0  0]
[ 0  0  0  0  0  0  0  0  0  0]
[ 0  0  0  0  0  0  0  0  0  0]
[ 0  0  0  0  0  0  0  0  0  0]
[ 0  0  0  0  0  0  0  0  0  0]]

resize()メソッドでは、必要に応じて要素を追加・削除し、NumPy配列を拡張・縮小できます。この例では、shapeの変更前よりも変更後の要素数のほうが多いため、不足分が0で埋められています。

今回はこの辺で終わりとさせていただきます。

お読みいただきましてありがとうございました。

この記事が気に入ったらサポートをしてみませんか?