連結と分割
連結と分割
1. 学習内容
- ❶ 連結 — 軸に沿って結合する
- ❷ vstack / hstack — 便利関数
- ❸ スタック — 新しい次元を追加して結合する
- ❹ split / vsplit / hsplit — 配列の分割
- ❺ 繰り返し/タイル — 繰り返しと拡大
2. ある開発者の実話
(1) 問題点
アリスは3か月分の売上データを持っており、各月のデータは4×3配列(4つの商品×3つの地域)として格納されています。彼女はこれらを1つの大きなテーブルに統合したいのですが、concatenateでどの軸を使用すべきか、いつも混同してしまいます。
(2) 解決策
ボブは図を描いて説明する。「軸0に沿って行が増え、軸1に沿って列が増える。」 concatenate(axis=0)は縦に積み重ねられ、concatenate(axis=1)は横に積み重ねられる。
(3) 成果
連結と分割の操作を習得したアリスは、1つのコマンドで月次データを統合したり、四半期ごとに分割したり、tileを使用して予測テンプレートを拡張したりできるようになり、データ組み立ての効率が10倍向上しました。
3. 主要な概念
(1) np.concatenate — 軸に沿って結合する
np.concatenate は最も汎用性の高い結合関数であり、axis パラメータによって方向が制御されます。
PYTHON
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6]])
b = np.array([[7, 8, 9],
[10, 11, 12]])
# Along axis 0: stack vertically (rows increase)
c0 = np.concatenate([a, b], axis=0)
# [[ 1 2 3]
# [ 4 5 6]
# [ 7 8 9]
# [10 11 12]]
# Along axis 1: stack horizontally (columns increase)
c1 = np.concatenate([a, b], axis=1)
# [[ 1 2 3 7 8 9]
# [ 4 5 6 10 11 12]]
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ 注意: 以下のコードは、ローカルの Python 環境で実行する必要があります。
(2) vstack と hstack
PYTHON
import numpy as np
a = np.array([[1, 2],
[3, 4]])
b = np.array([[5, 6],
[7, 8]])
# vstack: same as concatenate(axis=0)
v = np.vstack([a, b])
print(v.shape) # (4, 2)
# hstack: same as concatenate(axis=1)
h = np.hstack([a, b])
print(h.shape) # (2, 4)
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ 注意: 以下のコードは、ローカルの Python 環境で実行する必要があります。
(3) スタック — 新たな次元との融合
stack は新しい軸を作成し、その軸に沿って結合します:
PYTHON
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
c = np.array([7, 8, 9])
s = np.stack([a, b, c])
print(s.shape) # (3, 3)
print(s)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ 注意: 以下のコードは、ローカルの Python 環境で実行する必要があります。
(4) split — 配列の分割
PYTHON
import numpy as np
a = np.arange(12).reshape(6, 2)
# Split into 3 equal parts
parts = np.split(a, 3)
print(len(parts)) # 3
print(parts[0].shape) # (2, 2)
print(parts[1].shape) # (2, 2)
print(parts[2].shape) # (2, 2)
# Split at specific indices
parts2 = np.split(a, [2, 4])
print([p.shape for p in parts2]) # [(2,2), (2,2), (2,2)]
# vsplit: split along axis 0 (vertical)
# hsplit: split along axis 1 (horizontal)
v = np.vsplit(a, 3) # same as split(a, 3, axis=0)
h = np.hsplit(a, 2) # split columns
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ 注意: 以下のコードは、ローカルの Python 環境で実行する必要があります。
(5) 繰り返しとタイル張り
PYTHON
import numpy as np
a = np.array([1, 2, 3])
# repeat: repeat each element
print(np.repeat(a, 3)) # [1 1 1 2 2 2 3 3 3]
# tile: repeat the entire array
print(np.tile(a, 3)) # [1 2 3 1 2 3 1 2 3]
# 2D tile
b = np.array([[1, 2], [3, 4]])
print(np.tile(b, (2, 3)).shape) # (4, 6)
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ 注意: 以下のコードは、ローカルの Python 環境で実行する必要があります。
(1) ▶ サンプル
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
: 連結と積み重ねの比較 (難易度 ⭐)
PYTHON
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print("concatenate:", np.concatenate([a, b]))
# [1 2 3 4 5 6]
print("stack:", np.stack([a, b]))
# [[1 2 3]
# [4 5 6]]
print("vstack:", np.vstack([a, b]))
# [[1 2 3]
# [4 5 6]]
print("hstack:", np.hstack([a, b]))
# [1 2 3 4 5 6]
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ 注意: 以下のコードは、ローカルの Python 環境で実行する必要があります。
4. 比較表
(1) 連結の方法
| 関数 | 軸 | 形状の要件 | 結果としての形状の変化 |
|---|---|---|---|
concatenate |
指定済み | 結合軸を除き同様 | 結合軸の合計 |
vstack |
0 | 列数は同じ | 行数が増加 |
hstack |
1 | 行数は同じ | 列数が増加 |
stack |
新しい軸 | 形状は完全に同じ | 新しい次元が追加された |
(2) リピートとタイル
| 関数 | 動作 | 例 |
|---|---|---|
repeat(3) |
各要素を3回繰り返す | [1,2] → [1,1,1,2,2,2] |
tile(3) |
配列全体を3回繰り返す | [1,2] → [1,2,1,2,1,2] |
(1) ▶ サンプル:array_split を使った不均等な分割(難易度 ⭐⭐)
PYTHON
import numpy as np
a = np.arange(10)
# split requires equal parts — raises error for 3 parts
# array_split handles uneven splits gracefully
parts = np.array_split(a, 3)
for i, p in enumerate(parts):
print(f"Part {i}: shape={p.shape}, values={p}")
# 2D array_split
b = np.arange(20).reshape(5, 4)
parts_2d = np.array_split(b, 3)
for i, p in enumerate(parts_2d):
print(f"2D Part {i}: shape={p.shape}")
出力:
TEXTパート 0: shape=(4,), values=[0 1 2 3] 第1部:shape=(3,)、values=[4 5 6] 第2部:shape=(3,)、values=[7 8 9] 2D パート 0: shape=(2, 4) 2D 第1部:shape=(2, 4) 2D 第2部:shape=(1, 4)
(2) ▶ サンプル:データの拡張のための繰り返しとタイル化(難易度 ⭐)
PYTHON
import numpy as np
a = np.array([1, 2, 3])
# repeat: repeat each element individually
print("repeat:", np.repeat(a, 3))
# tile: repeat the entire array
print("tile:", np.tile(a, 3))
# Practical: expand a pattern
pattern = np.array([[1, 0], [0, 1]])
grid = np.tile(pattern, (2, 3))
print("Tiled pattern:\n", grid)
print("Shape:", grid.shape)
出力:
TEXT繰り返し:[1 1 1 2 2 2 3 3 3] tile: [1 2 3 1 2 3 1 2 3] タイル状の模様: [[1 0 1 0 1 0] [0 1 0 1 0 1] [1 0 1 0 1 0] [0 1 0 1 0 1]] 形状: (4, 6)
❓ よくある質問
Q 「concatenate」と「stack」の違いは何ですか?
A 「concatenate」は、既存の軸に沿って既存の配列を結合するもので、新しい次元は追加されません。「stack」は新しい軸を作成し、その軸に沿って結合することで、次元を1つ追加します。
Q 形状の異なる配列を連結することはできますか?
A 連結軸を除くすべての次元で一致している必要があります。たとえば、軸 0 に沿って連結する場合、配列の列数が同じでなければなりません。
Q 配列を等しくない数に分割するとどうなりますか?
A np.split は等しい分割を必要とします。等しくない場合はエラーが発生します。等しくない分割を行う場合は、余りを適切に処理してくれる np.array_split を使用してください。
📖 まとめ
concatenateは既存の軸に沿って結合します。結合軸を除き、軸は一致している必要があります。vstack/hstackは、軸 0 と軸 1 の連結を表すショートカットですstackは新しい次元を作成し、データのバッチ処理を行う際に役立ちますsplit/vsplit/hsplitは、配列を等分するか、特定のインデックスで分割しますrepeatは要素を繰り返し、tileは配列全体を繰り返します
📝 練習問題
-
初心者向け(難易度 ⭐):3×4のランダムな数値の配列を2つ作成します。それらをまず0軸に沿って、次に1軸に沿って連結します。その結果の形状を出力してください。
-
中級(難易度 ⭐⭐):長さ5の1次元配列を3つ作成してください。
stackを使用して、これらを3×5の配列に結合してください。その後、vstackを使用して、それぞれの形状を比較してください。 -
上級(難易度 ⭐⭐⭐):12×8の配列を作成します。それを3等分し、さらにインデックス [3, 7] の位置で分割します。
np.tileを使用して、2x2 のパターンを 8x8 のグリッドに繰り返し配置してください。