Remrinのpython攻略日記

python3に入門しました。python3についてあれこれとサンプルコードとか。

NumPyの使い方(4) 形状変換と転置

NumPyの形状変換と転置について。
 

reshape()、resize()

 タプルでshapeを指定して形状を変換する。
 変換前後で全要素数が一致しないときはValueError
 -1を指定した軸はNumPyが自動で判断。
 もとの配列を参照を得るので、値変更は元の配列に及ぶ。 
 np.resize()だと、コピーを取得するので、値変更をしても元の配列は保存される。
  np.resize()は総要素数が増えた場合は値を繰り返して埋める。
  ndarray.resize()は総要素数が増えたときはゼロで埋める。

import numpy as np

a1 = np.array(range(12))
print(a1)  # [0  1  2  3  4  5  6  7  8  9 10 11 12]

print(a1.reshape(4, 3))
# [[ 0  1  2]
#  [ 3  4  5]
#  [ 6  7  8]
#  [ 9 10 11]]

print(a1.reshape(4, 3).reshape(2, 6))
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]]

print(a1.reshape(6, -1))
# -1を指定した軸は、NumPyが自動で判断
#[[ 0  1]
# [ 2  3]
# [ 4  5]
# [ 6  7]
# [ 8  9]
# [10 11]]

# print(a1.reshape(6, 3))
# ValueError: total size of new array must be unchanged

 

flatten(), ravel()

 1次元の配列へ変換する。
 flatten() 必ずコピーを返す。
 raval()  必要がなければコピーは作らない。
 デフォルトでは行優先だが、列優先にする場合は"F"を引数にする。

a2 = np.arange(9).reshape(3, 3)
print(a2.flatten())
# [0 1 2 3 4 5 6 7 8]

print(a2.flatten("F"))
# [0 3 6 1 4 7 2 5 8]

 

転置.Tとtranspose()

・2次元配列の行列変換は.T
・transpose()は軸の順序を指定できる。
 
2次元配列のでの例

a1 = np.array(range(8)).reshape(4, 2)
print(a1)
# [[0 1]
#  [2 3]
#  [4 5]
#  [6 7]]

print(a1.T)
# [[0 2 4 6]
#  [1 3 5 7]]

# a1.T と a1 の内積
print(np.dot(a1.T, a1))
# [[56 68]
#  [68 84]]

print(a1.transpose(0, 1))
# 元の配列を同じ形
# [[0 1]
#  [2 3]
#  [4 5]
#  [6 7]]

print(a1.transpose(1, 0))
# 元の配列の0番の軸(行)を1番の軸(縦)に、1番軸を0番に
# [[0 2 4 6]
#  [1 3 5 7]]

 

・transpose(2, 0, 1)とは
 3次元配列で、shapeが(元の2番軸, 元の0番軸, 元の1番軸)にすることを表す。
 
3次元配列での例

a1 = np.array(range(24)).reshape(2, 3, 4)
print(a1)
# [[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#
#  [[12 13 14 15]
#   [16 17 18 19]
#   [20 21 22 23]]]

print(a1.transpose(0, 1, 2))
# 元の配列と同じ
# [[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#
#  [[12 13 14 15]
#   [16 17 18 19]
#   [20 21 22 23]]]

print(a1.transpose(0, 2, 1))
# 最も外側の次元は変えずに内側の行と列を入れ替える
# shapeは(2, 4, 3)となる。
# [[[ 0  4  8]
#   [ 1  5  9]
#   [ 2  6 10]
#   [ 3  7 11]]
#
#  [[12 16 20]
#   [13 17 21]
#   [14 18 22]
#   [15 19 23]]]

print(a1.transpose(1, 0, 2))
# transpose(1, 0, 2)とは、shapeが(元の1番軸、元の0番軸、元の2番軸)
# 列は変えずに、行と外側を入れ替えて、shapeは(3, 2, 4)となる。
# [[[ 0  1  2  3]
#   [12 13 14 15]]
#
#  [[ 4  5  6  7]
#   [16 17 18 19]]
#
#  [[ 8  9 10 11]
#   [20 21 22 23]]]

 
・3次元配列の軸の方向に注意
f:id:rare_Remrin:20170513132338p:plain
 

swapaxes()

・swapaxes()で特定の2つの軸を入れかれられる。
 「axes」は「axis」の複数形。
 3次元配列でswapaxes(0, 2)だと、0番軸と2番軸を交換する。
 つまり、transpose(2, 1, 0)と同義

 2次元配列での転置.Tは、swapaxes(1, 0)と同義。

print(a1.swapaxes(0, 1))  # transpose(1, 0, 2)と同義
# [[[ 0  1  2  3]
#   [12 13 14 15]]
#
#  [[ 4  5  6  7]
#   [16 17 18 19]]
#
#  [[ 8  9 10 11]
#   [20 21 22 23]]]