NumPy配列の一次元化:ravel()とflatten()を徹底解説
NumPyで多次元配列を扱っていると、配列を1次元(平坦化)に変換したい場面によく遭遇します。例えば、機械学習のモデルに入力する際や、特定の計算を行う前処理として必要になることがあります。NumPyには、この一次元化を実現するためのメソッドとして ravel() と flatten() が用意されています。
これら二つのメソッドは似たような結果をもたらしますが、内部的な挙動や使いどころに違いがあります。この記事では、ravel() と flatten() の使い方、そしてそれぞれの違いについて、簡潔なコード例を交えながら解説します。
ravel() と flatten() の基本的な使い方
どちらのメソッドも、多次元のNumPy配列を1次元の配列に変換します。
ravel() の使い方
ravel() は、元の配列と同じデータビューを返すことが一般的です。つまり、ravel() で平坦化された配列を変更すると、元の配列も影響を受ける可能性があります。
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(f"元の配列:\n{arr}\n")
# ravel()で一次元化
raveled_arr = arr.ravel()
print(f"ravel()で一次元化:\n{raveled_arr}\n")
# raveled_arrを変更してみる
raveled_arr[0] = 99
print(f"raveled_arr変更後:\n{raveled_arr}\n")
print(f"元の配列(変更されたか確認):\n{arr}")
実行結果:
元の配列:
[[1 2 3]
[4 5 6]]
ravel()で一次元化:
[1 2 3 4 5 6]
raveled_arr変更後:
[99 2 3 4 5 6]
元の配列(変更されたか確認):
[[99 2 3]
[ 4 5 6]]
上記の例からわかるように、raveled_arr を変更すると元の arr も変更されています。これは ravel() が元のデータのビューを返しているためです。
flatten() の使い方
flatten() は、常に元の配列のデータのコピーを返します。そのため、flatten() で平坦化された配列を変更しても、元の配列には影響がありません。
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(f"元の配列:\n{arr}\n")
# flatten()で一次元化
flattened_arr = arr.flatten()
print(f"flatten()で一次元化:\n{flattened_arr}\n")
# flattened_arrを変更してみる
flattened_arr[0] = 99
print(f"flattened_arr変更後:\n{flattened_arr}\n")
print(f"元の配列(変更されたか確認):\n{arr}")
実行結果:
元の配列:
[[1 2 3]
[4 5 6]]
flatten()で一次元化:
[1 2 3 4 5 6]
flattened_arr変更後:
[99 2 3 4 5 6]
元の配列(変更されたか確認):
[[1 2 3]
[4 5 6]]
この例では、flattened_arr を変更しても元の arr は変更されていません。これは flatten() が元のデータのコピーを返しているためです。
ravel() と flatten() の違いと使い分け
これまでの説明で、ravel() がビューを返し、flatten() がコピーを返すという点が最も重要な違いであることがお分かりいただけたでしょう。
主な違い
| 特徴 | ravel() |
flatten() |
| 返り値 | 元の配列のビュー(基本) | 元の配列のコピー |
| メモリ | 効率的(新しいメモリを確保しない) | 新しいメモリを確保する |
| 速度 | 速い(コピーのコストがないため) | やや遅い(コピーのコストがあるため) |
| 使用対象 | ndarray のメソッド、numpy.ravel 関数としても利用可能 |
ndarray のメソッドのみ |
どちらを選ぶべきか?
-
元の配列への影響を許容する場合、またはメモリ効率や速度を重視する場合は
ravel()を使うと良いでしょう。特に大きな配列を扱う際には、コピーによるメモリ消費や処理時間の増加を抑えることができます。 -
元の配列に影響を与えたくない場合は、必ず
flatten()を使ってください。これにより、意図しないデータの変更を防ぎ、コードの安全性を高めることができます。
一般的には、元の配列を変更したくないケースが多いため、flatten() を使うのが安全策と言えます。しかし、パフォーマンスがボトルネックになるような場面では、ravel() の利用も検討する価値があります。
まとめ
NumPy配列の一次元化には ravel() と flatten() の二つの選択肢があります。両者の主な違いは「ビューを返すか、コピーを返すか」という点に集約されます。この違いを理解し、目的や状況に応じて適切なメソッドを使い分けることが、効率的かつ安全なNumPyプログラミングへの鍵となります。



