Numpyの使い方(13) 結合・分割
Numpyの配列の結合・分割について。
np.concatenate()
2個以上の配列を軸指定して結合する。
軸指定オプションのaxisはデフォルトが0
マスクは保存されない。(マスクについては別の記事で)
import numpy as np a1 = np.array([[1, 2, 3], [4, 5, 6]]) a2 = np.array([[7, 8, 9], [0, 11, 12]]) print(np.concatenate([a1, a2], axis=0)) # [[ 1 2 3] # [ 4 5 6] # [ 7 8 9] # [ 10 11 12]] print(np.concatenate([a1, a2], axis=1)) # [[ 1 2 3 7 8 9] # [ 4 5 6 10 11 12]]
・軸axisの指定はすでに存在している軸のみ。
(Join a sequence of arrays along an existing axis.)
1次元配列:axis=0
2次元配列:axis=0, axis=1
3次元配列:axis=0, axis=1, axis=2
N次元配列:axis=[0, N) 0以上N未満
v1 = np.array([1, 2, 3]) v2 = np.array([4, 5, 6]) print(np.concatenate([v1, v2], axis=0)) # [1 2 3 4 5 6] # print(np.concatenate([v1, v2], axis=1)) # IndexError: axis 1 out of bounds [0, 1)
・結合の方向にかかわらず、配列の次元が同じでないと結合できない。
a1 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 2次元配列 a2 = np.array([10, 11, 12]) # 1次元配列 print(np.concatenate([a1, a2], axis=0)) # ValueError: all the input arrays must have same number of dimensions
行列(2次元配列)にベクトル(1次元配列)を結合させるとエラーだが、
ベクトルを2次元で表記すると結合できる。
a1 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) a2 = np.array([[10, 11, 12]]) # 2重の[[]]でベクトルを2次元で表記 print(np.concatenate([a1, a2], axis=0)) # [[ 1 2 3] # [ 4 5 6] # [ 7 8 9] # [10 11 12]] print(np.concatenate([a1, a2.T], axis=1)) # [[ 1 2 3 10] # [ 4 5 6 11] # [ 7 8 9 12]]
・ベクトル(1次元配列)を行列(2次元配列)に変換する方法
# ndim=1 のベクトルを ndim=2の横ベクトルに変換 v1 = np.array([1, 2, 3]) v2 =np.reshape(v1, (1, v1.shape[0])) print(v2.shape) # (1, 3) print(v2) # [[1 2 3]] # ndim=1 のベクトルを ndim=2の縦ベクトルに変換 v1 = np.array([1, 2, 3]) v3 =np.reshape(v1, (v1.shape[0], 1)) print(v3.shape) # (3, 1) print(v3) # [[1] # [2] # [3]]
・shapeが異なっていても結合できるが、結合方向は揃える。
a1 = np.array([[1, 2, 3], [4, 5, 6]]) a2 = np.array([[7, 8, 9], [10, 11, 12], [13, 14, 15]]) print(np.concatenate([a1, a2], axis=0)) # [[ 1 2 3] # [ 4 5 6] # [ 7 8 9] # [10 11 12] # [13 14 15]] #print(np.concatenate([a1, a2], axis=1)) # ValueError: all the input array dimensions except for the concatenation axis must match exactly
np.vstack(), np.hstack()、np.row_stack()、np.column_stack()、np.dstack()
concatenate()は汎用で軸の指定をできるが、それぞれの軸に対応した関数もある。
縦方向の結合:vstack()、row_stack()
横方向の結合:hstack()、column_stack()
深さ方向(axis=2)の結合:dstack()
a1 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) a2 = np.array([[10, 11, 12]]) # 2重の[[]]でベクトルを2次元で表記 print(np.vstack([a1, a2])) # [[ 1 2 3] # [ 4 5 6] # [ 7 8 9] # [10 11 12]] print(np.hstack([a1, a2.T])) # [[ 1 2 3 10] # [ 4 5 6 11] # [ 7 8 9 12]]
・dstack()の例
a1 = np.array([[1, 2, 3], [2, 3, 4]]) a2 = np.array([[5, 6, 7], [6, 7, 8]]) a1 = np.reshape(a1, (*a1.shape, 1)) a2 = np.reshape(a2, (*a2.shape, 1)) print(np.dstack([a1, a2])) # [[[1 5] # [2 6] # [3 7]] # # [[2 6] # [3 7] # [4 8]]]
3次元配列って、思っていたのとかなり違う。
軸変換しないと脳内のイメージと全然あわないですね。
イメージしていたのはこれです。
a1 = np.array([[1, 2, 3], [2, 3, 4]]) a2 = np.array([[5, 6, 7], [6, 7, 8]]) a1 = np.reshape(a1, (1, *a1.shape)) a2 = np.reshape(a2, (1, *a2.shape)) print(a1) # [[[1 2 3] # [2 3 4]]] print(np.vstack([a1, a2])) # [[[1 2 3] # [2 3 4]] # # [[5 6 7] # [6 7 8]]]
np.c_(), np.r_()
concatenate()の代わりに使えて、スライスからも配列を生成できる。
a1 = np.arange(6).reshape(2, 3) a2 = np.arange(100, 700, 100).reshape(2, 3) print(np.r_[a1, a2]) # [[ 0 1 2] # [ 3 4 5] # [100 200 300] # [400 500 600]] print(np.c_[a1, a2]) # [[ 0 1 2 100 200 300] # [ 3 4 5 400 500 600]] print(np.c_[np.r_[a1, a2, a1], np.arange(6)]) # [[ 0 1 2 0] # [ 3 4 5 1] # [100 200 300 2] # [400 500 600 3] # [ 0 1 2 4] # [ 3 4 5 5]] # スライスから配列を作れる print(np.r_[:4, 10, 10, 4:0:-1]) # [ 0 1 2 3 10 10 4 3 2 1] print(np.c_[:4, [10]*4, 4:0:-1]) # [[ 0 10 4] # [ 1 10 3] # [ 2 10 2] # [ 3 10 1]]
np.split()
配列の分割。
a = np.arange(12).reshape(6, 2) print(a) # [[ 0 1] # [ 2 3] # [ 4 5] # [ 6 7] # [ 8 9] # [10 11]] a1, a2, a3 =np.split(a, [1, 3]) #1行目と3行目の手前でsplit print(a1) # [[0 1]] print(a2) # [[2 3] # [4 5]] print(a3) # [[ 6 7] # [ 8 9] # [10 11]] a1, a2 =np.split(a, 2, axis=0) # 2等分 print(a1) # [[0 1] # [2 3] # [4 5]] print(a2) # [[ 6 7] # [ 8 9] # [10 11]] a1, a2 =np.split(a, 2, axis=1) # 2等分 print(a1) # [[ 0] # [ 2] # [ 4] # [ 6] # [ 8] # [10]] print(a2) # [[ 1] # [ 3] # [ 5] # [ 7] # [ 9] # [11]]
その他の分割関数
np.hsplit() | hstackの逆 |
np.vsplit() | vstackの逆 |
np.dsplit() | dstackの逆 |