NumPy配列結合完全ガイド|concatenate・stack・block・append全関数の使い方とサンプルコード
NumPyでは複数の配列を結合するための様々な関数が用意されています。本記事では、concatenate、stack、block、appendなど、配列結合の全手法を実践的なサンプルコードとともに詳しく解説します。
NumPy配列結合の基本概念
NumPyの配列結合には、大きく分けて以下の方法があります:
- concatenate: 既存の軸に沿って配列を結合
- stack: 新しい軸を作成して配列を積み重ね
- block: ブロック状に配列を組み合わせ
- append: 配列の末尾に要素を追加
concatenate:既存軸での配列結合
基本的な使い方
import numpy as np
# 1次元配列の結合
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
result = np.concatenate([arr1, arr2])
print("1次元結合:", result)
# 出力: [1 2 3 4 5 6]
axis=0での行方向結合
# 2次元配列の行方向結合
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6], [7, 8]])
result = np.concatenate([arr1, arr2], axis=0)
print("行方向結合:")
print(result)
# 出力:
# [[1 2]
# [3 4]
# [5 6]
# [7 8]]
axis=1での列方向結合
# 2次元配列の列方向結合
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6], [7, 8]])
result = np.concatenate([arr1, arr2], axis=1)
print("列方向結合:")
print(result)
# 出力:
# [[1 2 5 6]
# [3 4 7 8]]
複数配列の同時結合
# 3つ以上の配列を同時結合
arr1 = np.array([1, 2])
arr2 = np.array([3, 4])
arr3 = np.array([5, 6])
result = np.concatenate([arr1, arr2, arr3])
print("複数配列結合:", result)
# 出力: [1 2 3 4 5 6]
vstack・hstack:便利な結合関数
vstack(垂直結合)
# 垂直方向の結合
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
result = np.vstack([arr1, arr2])
print("vstack結果:")
print(result)
# 出力:
# [[1 2 3]
# [4 5 6]]
hstack(水平結合)
# 水平方向の結合
arr1 = np.array([[1], [2]])
arr2 = np.array([[3], [4]])
result = np.hstack([arr1, arr2])
print("hstack結果:")
print(result)
# 出力:
# [[1 3]
# [2 4]]
vstackとhstackの2次元配列での応用
# 2次元配列でのvstack
matrix1 = np.array([[1, 2], [3, 4]])
matrix2 = np.array([[5, 6]])
v_result = np.vstack([matrix1, matrix2])
print("2次元vstack:")
print(v_result)
# 2次元配列でのhstack
matrix1 = np.array([[1, 2], [3, 4]])
matrix2 = np.array([[5], [6]])
h_result = np.hstack([matrix1, matrix2])
print("2次元hstack:")
print(h_result)
stack:新しい軸での配列結合
基本的なstack操作
# stackで新しい軸を作成
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
result = np.stack([arr1, arr2])
print("stack結果:")
print(result)
print("形状:", result.shape)
# 出力:
# [[1 2 3]
# [4 5 6]]
# 形状: (2, 3)
axis指定でのstack
# axis=0でのstack(デフォルト)
arr1 = np.array([1, 2])
arr2 = np.array([3, 4])
stack_0 = np.stack([arr1, arr2], axis=0)
print("axis=0:", stack_0)
# axis=1でのstack
stack_1 = np.stack([arr1, arr2], axis=1)
print("axis=1:", stack_1)
# 出力:
# axis=0: [[1 2]
# [3 4]]
# axis=1: [[1 3]
# [2 4]]
2次元配列でのstack
# 2次元配列のstack
matrix1 = np.array([[1, 2], [3, 4]])
matrix2 = np.array([[5, 6], [7, 8]])
result = np.stack([matrix1, matrix2])
print("2次元stack:")
print(result)
print("形状:", result.shape)
# 形状: (2, 2, 2) - 3次元配列になる
dstack・column_stack・row_stack
dstack(深度方向結合)
# dstackで深度方向に結合
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6], [7, 8]])
result = np.dstack([arr1, arr2])
print("dstack形状:", result.shape)
print("dstack結果:")
print(result)
# 形状: (2, 2, 2)
column_stack(列として結合)
# 1次元配列を列として結合
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
result = np.column_stack([arr1, arr2])
print("column_stack:")
print(result)
# 出力:
# [[1 4]
# [2 5]
# [3 6]]
row_stack(行として結合)
# row_stackはvstackの別名
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
result = np.row_stack([arr1, arr2])
print("row_stack:")
print(result)
# vstackと同じ結果
block:ブロック状配列結合
基本的なblock操作
# 2x2ブロック構造の作成
arr1 = np.array([[1, 2]])
arr2 = np.array([[3, 4]])
arr3 = np.array([[5, 6]])
arr4 = np.array([[7, 8]])
result = np.block([[arr1, arr2],
[arr3, arr4]])
print("block結果:")
print(result)
# 出力:
# [[1 2 3 4]
# [5 6 7 8]]
異なるサイズのブロック結合
# 異なるサイズのブロック
top = np.array([[1, 2, 3]])
bottom_left = np.array([[4], [5]])
bottom_right = np.array([[6, 7], [8, 9]])
result = np.block([[top],
[bottom_left, bottom_right]])
print("異なるサイズblock:")
print(result)
# 出力:
# [[1 2 3]
# [4 6 7]
# [5 8 9]]
3次元ブロック
# 3次元ブロック構造
block1 = np.ones((2, 2, 2))
block2 = np.zeros((2, 2, 2))
result = np.block([[[block1, block2]]])
print("3次元block形状:", result.shape)
# 形状: (2, 2, 4)
append:配列への要素追加
1次元配列でのappend
# 基本的なappend
arr = np.array([1, 2, 3])
result = np.append(arr, 4)
print("append結果:", result)
# 出力: [1 2 3 4]
# 複数要素の追加
result = np.append(arr, [4, 5, 6])
print("複数append:", result)
# 出力: [1 2 3 4 5 6]
2次元配列でのappend
# 2次元配列のappend(axis指定)
arr = np.array([[1, 2], [3, 4]])
# 行の追加(axis=0)
new_row = np.array([[5, 6]])
result = np.append(arr, new_row, axis=0)
print("行追加:")
print(result)
# 列の追加(axis=1)
new_col = np.array([[7], [8]])
result = np.append(arr, new_col, axis=1)
print("列追加:")
print(result)
appendの注意点
# axisを指定しない場合は1次元化される
arr_2d = np.array([[1, 2], [3, 4]])
result = np.append(arr_2d, [5, 6])
print("axis未指定:", result)
# 出力: [1 2 3 4 5 6] (1次元化される)
実践的な応用例
データフレーム的な操作
# 学生データの結合例
students_a = np.array([['Alice', 85], ['Bob', 92]])
students_b = np.array([['Charlie', 78], ['David', 88]])
# 学生データの縦結合
all_students = np.vstack([students_a, students_b])
print("全学生データ:")
print(all_students)
# 科目データの横結合
math_scores = np.array([['85'], ['92'], ['78'], ['88']])
combined = np.hstack([all_students, math_scores])
print("科目追加後:")
print(combined)
時系列データの結合
# 時系列データの結合
jan_data = np.array([10, 15, 12, 18])
feb_data = np.array([20, 22, 19, 25])
mar_data = np.array([30, 28, 32, 35])
# 月別データの結合
quarterly_data = np.concatenate([jan_data, feb_data, mar_data])
print("四半期データ:", quarterly_data)
# 2次元として結合(月×日)
monthly_matrix = np.vstack([jan_data, feb_data, mar_data])
print("月別マトリックス:")
print(monthly_matrix)
画像データ風の結合
# 画像風データの結合
image1 = np.ones((3, 3))
image2 = np.zeros((3, 3))
image3 = np.full((3, 3), 0.5)
# 水平結合(横並び)
horizontal = np.hstack([image1, image2, image3])
print("水平結合形状:", horizontal.shape)
# 垂直結合(縦並び)
vertical = np.vstack([image1, image2, image3])
print("垂直結合形状:", vertical.shape)
# ブロック結合(2x2配置)
block_image = np.block([[image1, image2],
[image3, image1]])
print("ブロック結合形状:", block_image.shape)
パフォーマンス比較
結合方法による速度差
import time
# 大きな配列での性能テスト
arr1 = np.random.rand(1000, 1000)
arr2 = np.random.rand(1000, 1000)
# concatenate
start = time.time()
result1 = np.concatenate([arr1, arr2], axis=0)
time1 = time.time() - start
# vstack
start = time.time()
result2 = np.vstack([arr1, arr2])
time2 = time.time() - start
print(f"concatenate時間: {time1:.6f}秒")
print(f"vstack時間: {time2:.6f}秒")
メモリ効率的な結合
# リストからの一括結合(効率的)
arrays = [np.random.rand(100) for _ in range(10)]
efficient = np.concatenate(arrays)
# 逐次結合(非効率)
inefficient = arrays[0]
for arr in arrays[1:]:
inefficient = np.concatenate([inefficient, arr])
print("効率的結合形状:", efficient.shape)
print("非効率結合形状:", inefficient.shape)
エラーハンドリングと注意点
形状不一致エラー
# 形状エラーの例
try:
arr1 = np.array([[1, 2, 3]])
arr2 = np.array([[4, 5]]) # 異なる列数
result = np.concatenate([arr1, arr2], axis=0)
except ValueError as e:
print("形状エラー:", e)
# 正しい結合方法
arr1 = np.array([[1, 2, 3]])
arr2 = np.array([[4, 5, 6]]) # 同じ列数
result = np.concatenate([arr1, arr2], axis=0)
print("正しい結合:", result)
安全な結合関数
def safe_concatenate(arrays, axis=0):
"""安全な配列結合"""
if not arrays:
return np.array([])
# 形状チェック
shapes = [arr.shape for arr in arrays]
if axis == 0:
# 行結合:列数が同じかチェック
if len(set(shape[1:] for shape in shapes)) > 1:
print("警告: 列数が異なります")
return None
elif axis == 1:
# 列結合:行数が同じかチェック
if len(set(shape[0] for shape in shapes)) > 1:
print("警告: 行数が異なります")
return None
return np.concatenate(arrays, axis=axis)
# 使用例
arr1 = np.array([[1, 2]])
arr2 = np.array([[3, 4, 5]]) # 異なる列数
result = safe_concatenate([arr1, arr2], axis=0)
結合関数の使い分けガイド
目的別選択指針
# データの種類と目的に応じた選択例
# 1. 同じ形状の配列を単純結合
arr1 = np.array([1, 2])
arr2 = np.array([3, 4])
simple_concat = np.concatenate([arr1, arr2])
# 2. 行列として積み重ね
stack_result = np.vstack([arr1, arr2])
# 3. 列として並べる
column_result = np.column_stack([arr1, arr2])
# 4. 新しい次元で結合
new_dim = np.stack([arr1, arr2])
print("単純結合:", simple_concat)
print("行積み重ね:", stack_result)
print("列並べ:", column_result)
print("新次元:", new_dim)
選択フローチャート
def choose_concat_method(purpose):
"""結合方法の選択ガイド"""
guide = {
"同じ軸で結合": "concatenate",
"行として積み重ね": "vstack",
"列として並べる": "hstack",
"新しい軸で結合": "stack",
"ブロック構造": "block",
"末尾に追加": "append"
}
return guide.get(purpose, "concatenateを推奨")
# 使用例
print("行として積み重ね:", choose_concat_method("行として積み重ね"))
まとめ
NumPy配列の結合には様々な方法があり、目的に応じて適切な関数を選択することが重要です。
主要関数の特徴:
- concatenate: 汎用的な結合、axis指定で柔軟な操作
- vstack/hstack: 直感的な垂直/水平結合
- stack: 新しい次元での結合、形状変更あり
- block: 複雑なブロック構造の作成
- append: 配列への要素追加
選択のポイント:
- 形状維持: 元の次元を保つなら
concatenate - 新次元: 新しい軸が必要なら
stack - 直感性: 分かりやすさなら
vstack/hstack - 複雑性: ブロック構造なら
block
注意事項:
- 結合する配列の形状を事前に確認
- 大量データではメモリ使用量に注意
- パフォーマンスが重要な場合は事前測定
適切な結合方法を選択することで、効率的で読みやすいNumPyコードが書けるようになります。データ処理や科学計算において、これらの関数を使い分けて柔軟な配列操作を実現してください。

