NumPyのndarrayは、Pythonのリストとは違い、+
などの演算子で結合することができません。結合するためには、予め用意された関数を使用する必要があります。
本記事では、vstack
とhstack
を使用した結合方法を紹介します。よく使用される方法なので、覚えておくと役立つはずです。
np.hstack
まずは、np.hstack
関数のAPIドキュメントについて見ていきましょう。
numpy.hstack(tup, …, dtype=None, casting=’same_kind’)
params:
|パラメータ名|型|概要|
|:———–|:—-|:—|
|tup
|ndarrayのシーケンス|結合したい配列を指定します。
1次元配列以外はaxis=1以外同じshapeである必要があります。|
|dtype
|有効なdtype|指定したtypeになるように結合されます。|
|casting
||データ型の変換ルールを指定することができます。指定可能なオプションは以下のとおりです。
-
no
:変換しない
-
equiv
:バイトオーダーの変換のみ許可します。
- ’safe’:値が同等とされる変換のみ許可します
- ’same_kind’:float64とfloat32のような同様のデータ型でのみ変換を許可します
- ’unsafe’:強制的に変換を試みますが変換に失敗する可能性があります。
|
returns:
結合された配列(ndarray)が返されます。
hstack
関数は、2次元でいうと、水平方向に(horizontal)連結します。厳密にいうと、1次元の配列の場合は1番目のaxis方向に、2次元以上では2番目のaxis方向に連結します。結合後は、先頭を0番目としてshapeの1番目の要素数が増えることになります。
axis
に関しての詳細は、以下のページで解説しています。
NumPyの軸(axis)と次元数(ndim)とは何を意味するのか /features/numpy-axis.html
具体的に使用して確認してみましょう。
基本的な結合の仕方
In [1]: import numpy as np
In [2]: a = np.arange(12)
In [3]: b = np.arange(2)
In [4]: a
Out[4]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
In [5]: b
Out[5]: array([0, 1])
In [6]: np.hstack((a, b)) # 結合してみる。
Out[6]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1])
In [7]: c = np.arange(2).reshape(1, 2) # 2次元配列を作る。
In [8]: c
Out[8]: array([[0, 1]])
In [9]: np.hstack((a, c)) # aとつなげてみるとエラーが返ってくる。
---------------------------------------------------------------------------
(エラーメッセージが表示される)
ValueError: all the input arrays must have same number of dimensions
In [10]: d = np.arange(5).reshape(1, 5) # shapeを(1, 5)にする
In [11]: d
Out[11]: array([[0, 1, 2, 3, 4]])
In [12]: np.hstack((c, d)) # これなら結合できる。
Out[12]: array([[0, 1, 0, 1, 2, 3, 4]])
3次元配列での結合
3次元の多次元配列でも確認してみます。axis=1
の方向に連結するので、3次元配列ならその中に含まれている2次元配列の行方向に連結します。
In [13]: e = np.arange(12).reshape(2, 2, 3)
In [17]: f = np.arange(6).reshape(2, 1, 3) # 今度は3次元でやってみる。
In [18]: e
Out[18]:
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
In [19]: f
Out[19]:
array([[[0, 1, 2]],
[[3, 4, 5]]])
In [20]: np.hstack((e,f))
Out[20]:
array([[[ 0, 1, 2],
[ 3, 4, 5],
[ 0, 1, 2]],
[[ 6, 7, 8],
[ 9, 10, 11],
[ 3, 4, 5]]])
hstack関数が適用可能なshape
hstack
関数を適用可能なshapeについて確認してみます。以下の表にまとめたので、参考にしてください。shape
について知らない方は、以下のページを見ると分かると思います。
NumPyのndarrayのインスタンス変数shapeの意味 /features/numpy-shape.html
hstack できるshape の組み合わせ |
hstack できないshape の組み合わせ |
---|---|
(12, ), (2, ) | (12, ), (2, 1) |
(2, 3), (2, 4) | (2, 3), (4, 2) |
(2, 2), (2, 2) | (2, 2), (3, 2) |
(1, 2, 3), (1, 4, 3) | (1, 2, 3), (2, 2, 3) |
(2, 5, 3, 2), (2, 9, 3, 2) | (2, 5, 3, 2), (2, 5, 9, 2) |
axis=1が違うだけなら、hstack
で結合可能ですね。
np.vstack
np.vstack
の使用方法も見てみます。まずはAPIドキュメントから確認してみましょう。
numpy.vstack(tup, …, dtype=None, casting=’same_kind’)
params:
|パラメータ名|型|概要|
|:———–|:—-|:—|
|tup
|ndarrayのシーケンス|結合したい配列を指定します。
1次元配列以外はaxis=1以外同じshapeである必要があります。|
|dtype
|有効なdtype|指定したtypeになるように結合されます。|
|casting
||データ型の変換ルールを指定することができます。指定可能なオプションは以下のとおりです。
-
no
:変換しない
-
equiv
:バイトオーダーの変換のみ許可します。
- ’safe’:値が同等とされる変換のみ許可します
- ’same_kind’:float64とfloat32のような同様のデータ型でのみ変換を許可します
- ’unsafe’:強制的に変換を試みますが変換に失敗する可能性があります。
|
returns:
結合された配列(ndarray)が返されます。
先程のnp.hstack
とAPIドキュメントは全く一緒です。
こちらは、2次元でいうと垂直方向(vertical)に連結します。厳密にいうと、axis=0
の方向です。
基本的な結合
以下の例で使用方法を確認してみましょう。
In [1]: import numpy as np
In [2]: a = np.arange(12).reshape(-1,1) # 12個の要素を持つ縦ベクトル
In [3]: b = np.arange(2).reshape(-1,1) # 2個の要素を持つ縦ベクトル
In [4]: a
Out[4]:
array([[ 0],
[ 1],
[ 2],
[ 3],
[ 4],
[ 5],
[ 6],
[ 7],
[ 8],
[ 9],
[10],
[11]])
In [5]: b
Out[5]:
array([[0],
[1]])
In [6]: np.vstack((a,b)) # 結合してみる
Out[6]:
array([[ 0],
[ 1],
[ 2],
[ 3],
[ 4],
[ 5],
[ 6],
[ 7],
[ 8],
[ 9],
[10],
[11],
[ 0],
[ 1]])
In [7]: c = np.arange(2).reshape(1,2)
In [8]: c
Out[8]: array([[0, 1]])
In [9]: np.vstack((a,c)) # aとつなげてみるとエラーが返ってくる
---------------------------------------------------------------------------
(エラーメッセージが表示される)
ValueError: all the input array dimensions except for the concatenation axis must match exactly
In [12]: c
Out[12]: array([[0, 1]])
In [13]: d
Out[13]:
array([[0, 1],
[2, 3]])
In [14]: np.vstack((c, d))
Out[14]:
array([[0, 1],
[0, 1],
[2, 3]])
3次元配列の結合
次に、3次元配列でも確認してみます。2次元配列をもう1つ付け加える方向に配列同士を連結します。
In [15]: e = np.arange(24).reshape(4, 3, 2)
In [16]: f = np.arange(6).reshape(1, 3, 2)
In [17]: e
Out[17]:
array([[[ 0, 1],
[ 2, 3],
[ 4, 5]],
[[ 6, 7],
[ 8, 9],
[10, 11]],
[[12, 13],
[14, 15],
[16, 17]],
[[18, 19],
[20, 21],
[22, 23]]])
In [18]: f
Out[18]:
array([[[0, 1],
[2, 3],
[4, 5]]])
In [19]: g = np.vstack((e, f))
In [20]: g # 結合できた。
Out[20]:
array([[[ 0, 1],
[ 2, 3],
[ 4, 5]],
[[ 6, 7],
[ 8, 9],
[10, 11]],
[[12, 13],
[14, 15],
[16, 17]],
[[18, 19],
[20, 21],
[22, 23]],
[[ 0, 1],
[ 2, 3],
[ 4, 5]]])
In [21]: g.shape # shapeを確認してみる。
Out[21]: (5, 3, 2)
vstack関数が適用可能なshape
最後に、こちらもvstack
可能なshape
を確認してみます。以下の表にまとめたので、参考にしてください。
vstack できるshape の組み合わせ |
vstack できないshape の組み合わせ |
---|---|
(12, ), (2, ) | (12, ), (2, 1) |
(2, 3), (3, 3) | (2, 3), (2, 4) |
(2, 2), (2, 2) | (2, 2), (2, 5) |
(1, 2, 3), (4, 2, 3) | (1, 2, 3), (1, 2, 1) |
(2, 5, 3, 2), (9, 5, 3, 2) | (2, 5, 3, 2), (2, 7, 3, 2) |
axis=0
の要素数が違うだけなら、vstack
で結合することができます。