TUのブログ

Pythonを使ってデータ処理するときの忘備録

ndarrayの連結

numpyのndarrayを連結して1つのndarrayにしたい。そんなとき、僕はnumpyの関数であるconcatenate, stack, vstack, hstack, appendなどを良く使います。それぞれの用法について、メモしておきます。
最後まで読んで下さった方には言うまでもないかもしれませんが、内容は公式マニュアルから必要な部分を抜粋し、まとめたものに過ぎません。

手始めにndarrayをいくつか初期化しておきます。

import numpy as np

a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
c = np.array([[1,2],[3,4],[5,6]])

全て2次元の配列で、a,bはともに2行2列、cは3行2列です。


1. concatenate

さて、まずはconcatenateです。a,bを次の様に連結してみます。

np.concatenate([a,b],axis=0)

実行結果は、

array([[1, 2],
       [3, 4],
       [5, 6],
       [7, 8]])

となります。4行2列の2次元配列が返されます。

引数axisは連結の方向を指定します。0だと行が増え、1だと列が増える方向です。
ここで、大きさの異なる配列同士の連結を考えましょう。例えば、配列aとcは列の数は同じですが、行の数が異なります。この時、axis=0でconcatenateは可能ですが、axis=1ではエラーとなり実行できません。
また、concatenateは連結によって次元を上げることは出来ないので、2次元配列同士をaxis=2方向に連結することは出来ません。


2. stack

次はstackを見てみましょう。a,bをstackで連結してみます。

np.stack([a,b],axis=0)

実行結果は、

array([[[1, 2],
        [3, 4]],

       [[5, 6],
        [7, 8]]])

となります。この配列は3次元で、大きさは(2,2,2)になります。この例から分かるように、stackは次元を上げます。2つの配列を重ねるイメージです。
別のaxisを指定してみましょう。

np.stack([a,b],axis=1)

実行結果は、

array([[[1, 2],
        [5, 6]],

       [[3, 4],
        [7, 8]]])

となります。大きさは変わらず(2,2,2)ですが、配列の重なり方が先ほどの例とは異なります。axisは配列を重ねる方向を指定するといえるでしょう。
stackは異なる大きさの配列を連結することはできません。この例だと、配列aとcは連結できません。

やろうとすると、すべての入力配列の大きさを合わせろと怒られます。

ValueError: all input arrays must have the same shape


3. vstack, hstack

vstackとhstackですが、名前に惑わされてはいけません。できることはconcatenateと同様です。
vstackとhstackは引数にaxisを取りません。vstackはconcatenateでaxisを0に指定したもの、hstackはaxisを1に指定したものと同じです。

使い方は、

np.vstack([a,c])

こんな感じです。


4. append

最後にappendについて書きます。その名の通り、元の配列に別の配列を付け加えます。
appendはaxisを指定できますが、まずは指定せずにやってみます。

np.append(a,b)

実行結果は、

array([1, 2, 3, 4, 5, 6, 7, 8])

となります。

この様に、axisを指定しないと、元が多次元配列でも1次元にされてしまいます。
公式リファレンスには、"If axis is None, out is a flattened array."と書いてあります。

axis=0を指定してやれば、

array([[1, 2],
       [3, 4],
       [5, 6],
       [7, 8]])

この様に、concatenateと同様に働いてくれます。

以上、僕が良く使うndarrayの連結方法についてメモしておきました。