👋

第4回:NumPy配列の結合

に公開

はじめに

本記事は「Pythonで数値計算を行うためのNumPy入門」シリーズの第3回です.
このシリーズでは, "NumPyのよく使われる機能を分野ごとに理解すること" を目標としています.

Pythonで数値計算を行う際に欠かせないライブラリ「NumPy」について,基礎から応用まで体系的に学べます.

シリーズ構成予定(全10記事)

  1. NumPyのインストール 〜 arrayの基本
  2. 配列の追加・挿入・コピー
  3. 配列の作成(ones / zeros / arange / linspace / eye)
  4. 配列の結合(hstack / vstack / concatenate)(本記事)
  5. 条件抽出と検索(where / clip / unique)(公開後にリンクを追加する予定)
  6. 統計処理(mean / std / median ほか)(公開後にリンクを追加する予定)
  7. 線形代数(dot / inv / det / norm)(公開後にリンクを追加する予定)
  8. 乱数生成(rand / randint / normal)(公開後にリンクを追加する予定)
  9. 三角関数と角度変換(sin / arctan2 ほか)(公開後にリンクを追加する予定)
  10. ファイル入出力(savetxt / loadtxt)(公開後にリンクを追加する予定)

私のNumpyライブラリのバージョンは "1.26.4" です.

本記事のゴール

本記事では, 配列の結合 を学んでいきます.ベクトルや行列の結合方法を説明します.

今回扱う関数は以下の3つです.

関数 内容
np.hstack() 配列を 横(horizontal) 方向に結合
np.vstack() 配列を 縦(vertical) 方向に結合
np.concatenate() 配列を 任意 方向に結合

上記の関数を理解することで,小さな配列を組み合わせて大きな配列を作る ことができるようになります.

NumPyライブラリの読み込み

NumPyを使うためには,まずライブラリの読み込みから始めます.

import numpy as np

numpyライブラリを "np" という名前として,扱えるようにライブラリを読み込んでいます.
以降では "np" という名前を使っていきます.

np.hstack() (配列を 横(horizontal) 方向に結合)

配列を 横(horizontal) 方向に結合する np.hstack() 関数に関して説明します.

# 適当なベクトルを作成
vec1 = np.array([1, 2, 3])
vec2 = np.array([2, 3, 4])

# np.hstack() によるベクトルとベクトルを横方向に結合
vec3 = np.hstack((vec1, vec2))
print(vec3)
# 出力:[1 2 3 2 3 4]


# 適当な列ベクトルを作成
vec4 = np.array([[10], [20]])
# 適当な行列を作成
mat1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
mat2 = np.array([[2, 3, 4, 5], [6, 7, 8, 9]])

# np.hstack() による行列と列ベクトルを横方向に結合
mat3 = np.hstack((mat1, vec4))
print(mat3)
# 出力:[[1 2 3 4 10]
#       [5 6 7 8 20]]

# np.hstack() による行列と行列を横方向に結合
mat4 = np.hstack((mat1, mat2))
print(mat4)
# 出力:[[1 2 3 4 2 3 4 5]
#       [5 6 7 8 6 7 8 9]]

# np.hstack() による行列とベクトルを横方向に結合 (エラー発生)
mat5 = np.hstack((mat1, vec1))
# エラー内容:ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)
# 次元数が異なるエラーの発生

np.hstack() は配列を横方向に結合することができます.配列に列を追加するイメージです.
注意点として,配列を結合する際には,形状(shape)の一致が重要です.
結合する方向以外の次元が一致する必要があります.np.hstack() では,行数の一致が重要です.

ValueError のエラー内容に関して説明します.
内容としては,np.hstack() による配列の結合では,行数を一致させる必要があります.変数 mat1 の行数は "2" ですが,変数 vec1 の行数は "1" ですので,行数が異なることによる ValueError が発生しました.

np.vstack() (配列を 縦(vertical) 方向に結合)

配列を 縦(vertical) 方向に結合する np.vstack() 関数に関して説明します.

# 適当なベクトルを作成
vec1 = np.array([1, 2, 3])
vec2 = np.array([2, 3, 4])

# np.vstack() によるベクトルとベクトルを縦方向に結合
vec3 = np.vstack((vec1, vec2))
print(vec3)
# 出力:[[1 2 3]
#       [2 3 4]]


# 適当なベクトルを作成
vec4 = np.array([10, 20, 30, 40])
# 適当な行列を作成
mat1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
mat2 = np.array([[2, 3, 4, 5], [6, 7, 8, 9]])

# np.vstack() による行列とベクトルを縦方向に結合
mat3 = np.vstack((mat1, vec4))
print(mat3)
# 出力:[[ 1  2  3  4]
#       [ 5  6  7  8]
#       [10 20 30 40]]

# np.vstack() による行列と行列を縦方向に結合
mat4 = np.vstack((mat1, mat2))
print(mat4)
# 出力:[[1 2 3 4]
#       [5 6 7 8]
#       [2 3 4 5]
#       [6 7 8 9]]

# np.vstack() による行列とベクトルを縦方向に結合 (エラー発生)
mat5 = np.vstack((mat1, vec1))
# エラー内容:ValueError: all the input array dimensions except for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 4 and the array at index 1 has size 3

np.vstack() は配列を縦方向に結合することができます.配列に行を追加するイメージです.
注意点として,配列を結合する際には,形状(shape)の一致が重要です.
結合する方向以外の次元が一致する必要があります.np.vstack() では,列数の一致が重要です.

ValueError のエラー内容に関して説明します.
内容としては,np.vstack() による配列の結合では,列数を一致させる必要があります.変数 mat1 の列数は "4" ですが,変数 vec1 の列数は "3" ですので,列数が異なることによる ValueError が発生しました.

np.concatenate() (配列を 任意 方向に結合)

配列を 任意 方向に結合する np.concatenate() 関数に関して説明する.

# 適当なベクトルを作成
vec1 = np.array([1, 2, 3])
vec2 = np.array([2, 3, 4])
# ベクトルを1行3列の行列へ変換
vec1_reshape = vec1.reshape(1, -1)
vec2_reshape = vec2.reshape(1, -1)

# np.concatenate() によるベクトルとベクトルを縦方向(axis=0)に結合
vec3 = np.concatenate((vec1_reshape, vec2_reshape), axis=0)
print(vec3)
# 出力:[[1 2 3]
#       [2 3 4]]
# np.concatenate() によるベクトルとベクトルを横方向(axis=1)に結合
vec4 = np.concatenate((vec1_reshape, vec2_reshape), axis=1)
print(vec4)
# 出力:[[1 2 3 2 3 4]]


# 適当なベクトルを作成
vec5 = np.array([10, 20, 30, 40])
vec6 = np.array([[10], [20]])
# ベクトルを1行4列の行列へ変換
vec5_reshape = vec5.reshape(1, -1)
# 適当な行列を作成
mat1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
mat2 = np.array([[2, 3, 4, 5], [6, 7, 8, 9]])

# np.concatenate() による行列とベクトルを横方向(axis=0)に結合
mat3 = np.concatenate((mat1, vec5_reshape), axis=0)
print(mat3)
# 出力:[[ 1  2  3  4]
#       [ 5  6  7  8]
#       [10 20 30 40]]
# np.concatenate() による行列とベクトルを縦方向(axis=1)に結合
mat4 = np.concatenate((mat1, vec6), axis=1)
print(mat4)
# 出力:[[ 1  2  3  4 10]
#       [ 5  6  7  8 20]]

# np.concatenate() による行列と行列を縦方向(axis=0)に結合
mat5 = np.concatenate((mat1, mat2), axis=0)
print(mat5)
# 出力:[[1 2 3 4]
#       [5 6 7 8]
#       [2 3 4 5]
#       [6 7 8 9]]
# np.concatenate() による行列と行列を横方向(axis=1)に結合
mat6 = np.concatenate((mat1, mat2), axis=1)
print(mat6)
# 出力:[[1 2 3 4 2 3 4 5]
#       [5 6 7 8 6 7 8 9]]

# np.concatenate() による行列とベクトルを横方向(axis=0)に結合 (エラー発生)
mat7 = np.concatenate((mat1, vec1), axis=0)
# エラー内容:ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)
# np.concatenate() による行列とベクトルを縦方向(axis=1)に結合 (エラー発生)
mat8 = np.concatenate((mat1, vec1), axis=1)
# エラー内容:ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)

np.concatenate() の引数 axis に関しての情報を下表にまとめます.

引数 axis の値 内容 同等の処理をする関数
0 配列を 方向に結合 np.vstack()
1 配列を 方向に結合 np.hstack()

np.concatenate() は配列を 任意 の方向に結合することができます.
np.hstack()np.vstack() は特定方向に対して結合するが,np.concatenate() は任意方向に対して結合できるため,汎用的に使用する事ができます.
np.hstack()np.vstack() を使用すると,配列の結合方向が明示的となるため,第三者が見たときにわかりやすくなります.また,np.concatenate() は引数 axis によって,配列の結合方向を決定する事ができるけど,axis を理解していないと想定外の方向に配列が結合してしまうので注意が必要となります.

まとめ

NumPyライブラリの hstack / vstack / concatenate を比較します.

操作 関数 注意点
配列を横(horizontal)方向に結合 np.hstack() 結合したい配列の行数を揃える必要あり
配列を縦(vertical)方向に結合 np.vstack() 結合したい配列の列数を揃える必要あり
配列を任意方向に結合 np.concatenate() 引数 axis を理解しないと,想定外の方向に配列が結合される

配列の結合方法を理解することで,小さな配列を組み合わせて大きな配列を作る ことができるようになります.

次回予告

第5回:「条件抽出と検索(where / clip / unique / isclose)」

  • np.where() (条件に一致する要素または値を取得)
  • np.clip() (配列の値を指定した範囲に収める)
  • np.unique() (配列の重複を除いて,ユニーク(唯一)な要素を抽出)
  • np.isclose() (配列の各要素が特定の値に近似しているかを判定)

「条件抽出と検索に関する方法」を説明します.

参考文献

本記事を作成するに当たって参考にしたサイトをまとめました.

Discussion