データサイエンスや機械学習の分野において、NumPyは欠かすことのできない基礎ライブラリの一つです。
大量のデータを効率的に処理する際、一つの大きな配列を複数の小さな配列に分割する作業が頻繁に発生します。
NumPyには配列を分割するための便利な関数が用意されており、その中でも「vsplit」と「hsplit」は直感的で使い勝手の良い関数です。
本記事では、これら2つの関数を中心に、実務で役立つ配列の分割テクニックを詳しく解説します。
NumPyにおける配列分割の基本概念
NumPyで配列を分割する際、最も汎用的な関数は numpy.split です。
しかし、多次元配列を扱う際には、どの方向に分割するのかを明示的に指定する必要があります。
そこで、垂直方向(行方向)に分割する vsplit と、水平方向(列方向)に分割する hsplit が非常に役立ちます。
これらの関数は、内部的には split 関数を呼び出していますが、軸(axis)の指定が固定されているため、コードの可読性が大幅に向上します。
特に、データの「特徴量」と「ラベル」を分ける際や、画像をグリッド状に切り出す際に、これらの関数は威力を発揮します。
hsplitによる水平方向(列方向)の分割
hsplit は、配列を水平方向、つまり列ごとに分割するための関数です。
2次元配列の場合、左から右へ切り分けるイメージを持つと理解しやすくなります。
hsplitの基本的な使い方
まずは、もっともシンプルな等分割の例を見てみましょう。
hsplit の第2引数に整数を渡すと、その数に等分されます。
import numpy as np
# 2行4列の配列を作成
array_2d = np.arange(8).reshape(2, 4)
print("元の配列:\n", array_2d)
# 水平方向に2分割(2つの 2x2 配列に分割)
result = np.hsplit(array_2d, 2)
print("分割後の配列1:\n", result[0])
print("分割後の配列2:\n", result[1])
元の配列:
[[0 1 2 3]
[4 5 6 7]]
分割後の配列1:
[[0 1]
[4 5]]
分割後の配列2:
[[2 3]
[6 7]]
このように、元の配列の列数が分割数で割り切れる場合、綺麗に等分割されます。
任意のインデックスで分割する
等分割だけでなく、特定の列番号を指定して分割することも可能です。
第2引数にリスト形式でインデックスを渡すと、その位置で配列が切り分けられます。
# インデックス1と3で分割
# [:, :1], [:, 1:3], [:, 3:] の3つに分かれる
result_custom = np.hsplit(array_2d, [1, 3])
for i, arr in enumerate(result_custom):
print(f"分割後の配列 {i+1}:\n", arr)
分割後の配列 1:
[[0]
[4]]
分割後の配列 2:
[[1 2]
[5 6]]
分割後の配列 3:
[[3]
[7]]
この手法は、データセットの特定の列だけを抽出したい場合に非常に効率的です。
vsplitによる垂直方向(行方向)の分割
次に、vsplit について解説します。
vsplit は配列を垂直方向、すなわち行ごとに分割するために使用されます。
上下に切り分けるイメージであり、多くのデータ処理において「サンプル(行)」を分ける際に利用されます。
vsplitの具体的な実装例
4行2列の配列を例に、上下に2分割する処理を確認しましょう。
# 4行2列の配列を作成
array_v = np.arange(8).reshape(4, 2)
print("元の配列:\n", array_v)
# 垂直方向に2分割
result_v = np.vsplit(array_v, 2)
print("分割後の配列1:\n", result_v[0])
print("分割後の配列2:\n", result_v[1])
元の配列:
[[0 1]
[2 3]
[4 5]
[6 7]]
分割後の配列1:
[[0 1]
[2 3]]
分割後の配列2:
[[4 5]
[6 7]]
このように、行方向にスライスされた新しい配列がリストとして返されます。
機械学習における活用シーン
vsplit は、機械学習における「訓練データとテストデータの分割」を手動で行う際などに便利です。
例えば、1000行のデータのうち、最初の800行を学習用、残りの200行を検証用に分けたい場合に重宝します。
「インデックス指定による分割」を使えば、任意の行数で正確に切り分けることができます。
# 800行目以降で分割する場合
# train_data, test_data = np.vsplit(large_dataset, [800])
vsplitとhsplitの機能比較
これらの関数の使い分けを整理するために、以下の表にまとめました。
| 関数名 | 分割方向 | 軸 (axis) | 主な用途 |
|---|---|---|---|
vsplit | 垂直方向 (Vertical) | axis=0 (行) | サンプルの分割、データの上下切り出し |
hsplit | 水平方向 (Horizontal) | axis=1 (列) | 特徴量の抽出、列データの分離 |
dsplit | 奥行き方向 (Depth) | axis=2 (深さ) | RGB画像のチャンネル分離など(3次元以上) |
注意点として、vsplit は1次元配列に対しては使用できません。
1次元配列を分割したい場合は、通常の split 関数を使用するか、配列を reshape で2次元に変形させてから vsplit を適用する必要があります。
分割時に発生しやすいエラーと対処法
配列分割を利用する際、最も遭遇しやすいエラーが ValueError です。
これは、指定した分割数で配列を均等に割ることができない場合に発生します。
# 3行の配列を2つに等分割しようとするとエラーになる
try:
err_array = np.zeros((3, 2))
np.vsplit(err_array, 2)
except ValueError as e:
print("エラーメッセージ:", e)
エラーメッセージ: array split does not result in an equal division
このエラーを回避するためには、以下のいずれかの方法を検討してください。
- 分割したい要素数を確認し、割り切れる数にデータを調整する。
- 等分割ではなく、「インデックス指定のリスト」を使用して分割箇所を明示する。
numpy.array_split関数を使用する(こちらは均等でなくても分割可能です)。
array_split は、指定した数で等分割できない場合でも、できるだけ均等になるようにサイズを調整して分割してくれるため、非常に柔軟です。
実践的な応用:画像データの分割
画像のピクセルデータもNumPy配列として扱われるため、これらの分割関数が多用されます。
例えば、1枚の大きな画像をグリッド状に分割して、小さなタイルとして処理する場合などです。
vsplit で行(縦)を切り分け、さらにそれぞれの結果に対して hsplit で列(横)を切り分けることで、タイル状のパーツを得ることができます。
# 仮の画像データ (100x100ピクセル)
image_data = np.random.rand(100, 100, 3)
# 縦に2分割
top, bottom = np.vsplit(image_data, 2)
# さらに横に2分割(4つのタイルができる)
top_left, top_right = np.hsplit(top, 2)
bottom_left, bottom_right = np.hsplit(bottom, 2)
print("タイルの形状:", top_left.shape)
タイルの形状: (50, 50, 3)
このような処理は、ディープラーニングの前処理や、画像解析のアルゴリズムを局所的に適用する際に非常に一般的です。
より高度な分割:dsplitの紹介
3次元以上の配列、特に画像チャンネル(RGBなど)を扱う場合には dsplit も重要です。
これは「深さ方向(axis=2)」に分割を行う関数です。
例えば、RGBの3チャンネルを持つ画像データを、Red、Green、Blueの各成分に分離したい場合に活用されます。
vsplit や hsplit と組み合わせて使うことで、多次元空間における自由自在なデータ操作が可能になります。
効率的なコーディングのためのTips
NumPyの関数を使いこなすコツは、「スライス表記」との使い分けにあります。
単一の部分配列を取り出すだけであれば、array[:50, :50] のようなスライス表記の方が簡潔です。
しかし、配列全体を構造的にバラバラにしたい場合は、vsplit や hsplit を使ったほうがコードの意図が明確になります。
「意図が伝わりやすいコード」を書くことは、チーム開発や将来の自分自身のデバッグにおいて極めて重要です。
「何のために分割しているのか」が関数名一目でわかる vsplit hsplit は、プロフェッショナルなコードにおいて推奨される選択肢です。
まとめ
NumPyにおける配列分割のテクニック、特に vsplit と hsplit について解説しました。
垂直方向への分割には vsplit、水平方向への分割には hsplit を使用することで、多次元配列を直感的かつ効率的に操作できます。
これらを使う際は、等分割が可能かどうかに注意し、必要に応じてインデックス指定や array_split を併用してください。
データの構造を自由自在に操るスキルは、データ分析やAI開発の基盤となります。
ぜひ今回の内容を、日々のプログラミングや研究・業務に役立ててください。
