ndarrayを扱うことは、多次元配列を操作する上でとても重要で効率的な方法だ。

今回はndarrayとして定義された行列の入れ替え(転置)について紹介する。

具体的な方法を説明する前に、ndarrayの転置は元の行列を再構成したビューを取得するため、コピーを生成するものではないということだけ覚えておいてほしい。

reshape関数でサンプルとなる行列を生成する

まずはサンプルとなる行列をreshape関数を使って生成する。

reshape関数は、ndarray配列の形状変換をする関数で、引数にタプルを指定すると、タプルの値に応じた次元・要素数(行列)の配列へと変換をおこなうことができる。

import numpy as np

arr = np.arange(15)
# array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])

arr.reshape((3, 5))
# array([[ 0,  1,  2,  3,  4],
#       [ 5,  6,  7,  8,  9],
#       [10, 11, 12, 13, 14]])

arr.reshape(15)
# array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])

属性Tを参照して行列を入れ替える

サンプルの行列(二次元配列)が用意できたので、早速行列を入れ替える方法を紹介する。

まず、ndarrayの属性Tを参照する方法を見ていこう。

import numpy as np

arr = np.arange(15).reshape((3, 5))

arr.T
# array([[ 0,  5, 10],
#       [ 1,  6, 11],
#       [ 2,  7, 12],
#       [ 3,  8, 13],
#       [ 4,  9, 14]])

属性Tを参照すると、元のndarrayの行列を転置した配列を結果として得ることができる。

なお、属性Tはあくまで参照なので、以下のように転置した結果に値を代入すると元のndarrayに変更が適用されてしまうので注意が必要だ。

もし転置した結果にのみ変更を適用したいのであればcopyメソッドを使うと良いだろう。

import numpy as np

arr = np.arange(15).reshape((3, 5))
arr2 = arr.T.copy()
arr2[0, 1] = 100

print(arr)
#[[ 0  1  2  3  4]
# [ 5  6  7  8  9]
# [10 11 12 13 14]]

print(arr2)
#[[  0 100  10]
# [  1   6  11]
# [  2   7  12]
# [  3   8  13]
# [  4   9  14]]

transpose関数で高次元配列の行列を入れ替える

行列の入れ替えはtranspose関数を利用しておこなうこともできる。

transpose関数は引数で軸の入れ替えを指定するが、様々なパターンがあるので例を見てもらった方が理解が早いだろう。

なお、引数の軸の指定については、タプルを指定しても同様の結果が得られる。

import numpy as np

arr = np.arange(15).reshape((3, 5))

arr.transpose()
# 引数が空の場合は属性Tと同じ結果が得られる
# array([[ 0,  5, 10],
#       [ 1,  6, 11],
#       [ 2,  7, 12],
#      [ 3,  8, 13],
#       [ 4,  9, 14]])

arr.transpose(0, 1)
# 軸の順番をそのままに指定した場合
# array([[ 0,  1,  2,  3,  4],
#       [ 5,  6,  7,  8,  9],
#       [10, 11, 12, 13, 14]])

arr.transpose(1, 0)
# 軸の順番を逆に指定した場合
# array([[ 0,  5, 10],
#       [ 1,  6, 11],
#       [ 2,  7, 12],
#      [ 3,  8, 13],
#       [ 4,  9, 14]])

次に多次元配列、今回は3次元配列のtranspose関数の使用例を見ていこう。

import numpy as np

arr = np.arange(16).reshape((2, 2, 4))
arr
# array(
#    [
#        [
#            [ 0,  1,  2,  3],
#            [ 4,  5,  6,  7]
#        ],
#       [
#           [ 8,  9, 10, 11],
#            [12, 13, 14, 15]
#       ]
#    ]
# )

arr.transpose((1, 0, 2))
# array(
#     [
#         [
#             [ 0,  1,  2,  3],
#             [ 8,  9, 10, 11]
#         ],
#        [
#            [ 4,  5,  6,  7],
#             [12, 13, 14, 15]
#        ]
#     ]
# )

arr.transpose((2, 0, 1))
# array(
#     [
#         [
#             [ 0,  4],
#             [ 8, 12]
#         ],
#        [
#            [ 1,  5],
#             [ 9, 13]
#        ],
#        [
#            [ 2,  6],
#             [10, 14]
#        ],
#        [
#            [ 3,  7],
#             [11, 15]
#        ]
#     ]
# )

少々複雑になってきたが、指定した軸のとおりに行列が入れ替わっていることが分かるだろう。

まとめ

機械学習の分野では行列やベクトル、内積の計算などの様々な場面で、今回取り上げた内容が頻出する。

機械学習の勉強に進むにあたり、避けては通れない道なので、しっかりとマスターしておきたいところだ。