numpy.hstackは、配列を水平に重ねていく関数です。「h」は「horizontal(水平の)」の頭文字です。「stack」は「重ねる」なので「水平に重ねる」ということです。
それでは、実際のコードを見て確認していきましょう。
1. numpy.hstack関数の使い方
まず、numpy.hstackの基本的な書き方を確認しましょう。
書き方:
np.hstack(tup)
パラメーター:
引数 | 型 | 解説 |
tup | sequence of ndarrays | ここで指定した配列同士を横に重ねます。2つ目の軸(axis=1)を除いて配列同士のshapeが合致している必要があります。ただし一次元配列同士の場合は揃っていなくても大丈夫です。 |
戻り値:
要素を重ねた新しいndarray |
一緒に確認したい関数:
- stack: 配列同士を新しい軸にそって重ねる。
- vstack: 配列同士を垂直に重ねる。
- dstack: 配列同士を奥行きで重ねる。
- concatenate: 配列同士を既に存在する軸にそって連結する。
- split: 二つ目の軸にそって配列を分割する。
- block:
numpy.hstackで1次元配列同士を重ねると1次元配列のまま列数が増えます。例えば、shape(N,)とshape(M,)の1次元配列を重ねると、shape(M+N,)の1次元配列になります。
2次元配列以上の場合は、numpy.concatenateで「axis=1」で連結していくのと同じことになります。
2次元配列では「axis=1」は列です。そのため、shape(a, N)とshape(a, M)の2次元配列を重ねると、shape(a, M+N)の2次元配列になります。
3次元配列同士の場合は、「axis=1」は行です。そのため行数を重ねていきます。例えば、shape(a, N, b)とshape(a, M, b)の配列を重ねると、shape(a, M+N, b)の3次元配列になります。
numpy.hstackは3次元までの配列を扱うのに適しています。例えば、「高さ・幅・r/g/b」の3つの軸をもつピクセルデータのようなデータを扱うときによく使われます。
それでは、使い方を確認していきましょう。
1.1. 1次元配列同士の場合は列を重ねる
まずは1次元配列同士の場合から見ていきましょう。
shape(N,)とshape(M,)の1次元配列を重ねると、shape(N+M,)の1次元配列になります。
以下のコードをご確認ください。shape(3,)とshape(3,)の1次元配列を重ねているので、shape(6,)の1次元配列が生成されています。
なお、コード内で使用しているnp.arange()は『numpy.arange – 色々な連番の配列を生成する方法』で解説しています。
import numpy as np
''' 1次元配列の列を重ねる。 '''
# 元の配列①を生成
arr1 = np.arange(3)
# 元の配列②を生成
arr2 = np.arange(3, 6)
# ①と②を重ねた新しい配列を生成
arr3 = np.hstack((arr1, arr2))
print('arr1: 元の配列①\n', arr1, '\n')
print('arr2: 元の配列②\n', arr2, '\n')
print('arr3: 新しい配列\n', arr3, '\n')
print('arr3のshape\n', arr3.shape, '\n')
print('arr3の次元数\n', arr3.ndim)
3つ以上の配列を重ねることもできます。以下のコードでは、shape(3,)の1次元配列を3つ重ねているので、shape(9,)の1次元配列が生成されています。
なお、重ねる配列の数に上限はありません。
''' 3つ以上の配列を重ねることもできます。 '''
# 元の配列③を生成
arr4 = np.arange(6, 9)
# ①と②と③を重ねた新しい配列を生成
arr5 = np.hstack((arr1, arr2, arr4))
print('arr5\n', arr5, '\n')
print('arr5のshape\n', arr5.shape, '\n')
print('arr5の次元数\n', arr5.ndim)
1次元配列同士の場合は、列数が異なる場合でも関係なく重ねることができます。以下のコードでは、shape(3,)とshape(4,)の1次元配列を重ねて、shape(7,)の1次元配列を生成しています。
''' 列数が異なる1次元配列同士も重ねることが可能です。 '''
# 4列(要素数4)の1次元配列④を生成
arr6 = np.arange(4)
print('arr1: 元の配列①\n', arr1, '\n')
print('arr6: 元の配列④\n', arr6, '\n')
print('新しい配列\n', np.hstack((arr1, arr6)))
1次元配列同士を重ねる場合はエラーの心配はありません。
1.2. 2次元配列同士の場合は列を重ねる
次に2次元配列同士の場合を見てみましょう。
2次元配列の「axis=1」は列です。そのため、shape(a, N)とshape(a, M)の2次元配列を重ねると、shape(a, M+N)と列が重ねられた2次元配列になります。行数は変わりません。
以下のコードでは、shape(2, 3)の2次元配列を2つ重ねているので、shape(2, 6)の2次元配列が生成されています。
なお、コード内で使用しているnp.reshapeは『numpy.reshape – 配列の形状を変換』で解説しています。
''' 2次元配列では同じ行にある要素を列で重ねます。 '''
# 元の2次元配列①を生成
arr7 = np.arange(6).reshape(2, 3)
# 元の2次元配列②を生成
arr8 = np.arange(6, 12).reshape(2, 3)
# ①と②を重ねた新しい配列を生成
arr9 = np.hstack((arr7, arr8))
print('arr7: 元の2次元配列①\n', arr7, '\n')
print('arr8: 元の2次元配列②\n', arr8, '\n')
print('arr9: 新しい配列\n', arr9, '\n')
print('arr9のshape\n', arr9.shape, '\n')
print('arr9の次元数\n', arr9.ndim)
2次元配列の場合は、列数が異なっても、行数さえ同じであれば、重ねることが可能です。
以下のコードでは、shape(2, 3)とshape(2, 4)の、列数が異なる配列を重ねて、shape(2, 7)の2次元配列が生成されています。
''' 2次元配列の場合は行数が合っていれば、列数が違ってもOK '''
# 2次元配列③を生成
arr10 = np.arange(6, 14).reshape(2, 4)
# 2次元配列①と③を重ねる
arr11 = np.hstack((arr7, arr10))
print('arr7: 元の2次元配列①\n', arr7, '\n')
print('arr10: 元の2次元配列③\n', arr10, '\n')
print('arr11: 新しい配列\n', arr11)
ただし、行数が異なっていればエラーになります。
以下のコードでは、shape(2, 3)と、shape(3, 3)の2次元配列を重ねようとしていますが、行数が異なるのでエラーになっています。
''' 行数が異なる2次元配列同士ではエラー '''
# 2次元配列④を生成
arr12 = np.arange(6, 15).reshape(3, 3)
print('arr7: 元の2次元配列①\n', arr7, '\n')
print('arr12: 元の2次元配列④\n', arr12, '\n')
# 2次元配列①と④は列数が異なるので重ねるとエラー
np.hstack((arr7, arr12))
1.3. 3次元配列同士の場合は行を重ねる
続いて、3次元配列同士の場合です。
3次元配列同士の場合は、「axis=1」は行ですので、行数を重ねていきます。例えば、shape(a, N, b)とshape(a, M, b)の配列を重ねると、shape(a, N+M, b)の3次元配列になります。
以下のコードでは、shape(3, 2, 3)の3次元配列同士を重ねているので、shape(3, 4, 3)の3次元配列が生成されています。
''' 3次元配列以上では同じ奥行き同士で行を重ねる。 '''
# 3次元配列①を生成
arr13 = np.arange(12).reshape(2, 2, 3)
# 3次元配列②を生成
arr14 = np.arange(12, 24).reshape(2, 2, 3)
# ①と②の行を重ねる
arr15 = np.hstack((arr13, arr14))
print('arr13: 元の3次元配列①\n', arr13, '\n')
print('arr14: 元の3次元配列②\n', arr14, '\n')
print('arr15: 新しい配列\n', arr15, '\n')
print('arr15のshape\n', arr15.shape, '\n')
print('arr15の次元数\n', arr15.ndim)
3次元配列の場合は、行として重ねられていくので、奥行き数と列数が揃っていれば連結可能です。
以下のコードでは、shape(2, 2, 3)とshape(2, 1, 3)の配列を重ねているので、shape(2, 3, 3)の3次元配列が生成されています。
''' 3次元配列の場合は、奥行き数と列数が揃っていればOK。 '''
# 3次元配列③を生成
arr16 = np.arange(12, 18).reshape(2, 1, 3)
# 3次元配列①と③を重ねる
arr17 = np.hstack((arr13, arr16))
print('arr13: 元の3次元配列①\n', arr13, '\n')
print('arr16: 元の3次元配列②\n', arr16, '\n')
print('arr17: 新しい配列\n', arr17, '\n')
print('arr17のshape\n', arr17.shape, '\n')
print('arr17の次元数\n', arr17.ndim)
しかし、奥行きと列数のどちらか一方でも揃っていない場合はエラーになります。
以下のコードでは、shape(2, 2, 3)とshape(2, 1, 4)の配列を重ねようとしていますが、行数および列数が異なるのでエラーになっています。
''' 奥行きや列数が揃っていなければエラーになります。 '''
# 3次元配列④を生成
arr18 = np.arange(12, 20).reshape(2, 1, 4)
print('arr13: 元の3次元配列①\n', arr13, '\n')
print('arr18: 元の3次元配列④\n', arr18, '\n')
# 配列①と④は行数や列数が揃っていないのでエラー
np.hstack((arr13, arr18))
2. まとめ
以上が、numpy.hstackの使い方です。同じような関数として以下も確認しておくと良いでしょう。
コメント