NumPyのndarrayは、Pythonのリストとは違い、+などの演算子で結合することができません。結合するためには、予め用意された関数を使用する必要があります。

本記事では、vstackhstackを使用した結合方法を紹介します。よく使用される方法なので、覚えておくと役立つはずです。

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で結合することができます。