以下の内容はhttps://pydocument.hatenablog.com/entry/2025/02/22/190329より取得しました。


NumPyの「flatten」「ravel」の使い方と使い分け – 配列を1次元化(平坦化)する

Python数値計算ライブラリNumPyには、多次元配列を1次元配列に変換(平坦化)するためのflattenravelという2つのメソッドがあります。どちらも似た機能を提供しますが、いくつかの違いがあります。この記事では、flattenravelの基本的な使い方と概要を説明し、それらの違いと使い分けについて解説します。

1. flatten の概要と基本的な使い方

概要

ndarray.flatten()は、多次元配列のコピーを1次元配列として返します。元の配列は変更されません。

基本的な使い方

import numpy as np

# 2次元配列を作成
arr2d = np.array([[1, 2, 3], [4, 5, 6]])
print(f"Original array:\n{arr2d}")

# flattenを使って1次元化 (コピーが返される)
arr1d_flatten = arr2d.flatten()
print(f"flatten: {arr1d_flatten}")

# flattenで作成した配列を変更しても、元の配列は変わらない
arr1d_flatten[0] = 100
print(f"flatten (modified): {arr1d_flatten}")
print(f"Original array after modification:\n{arr2d}")

出力

Original array:
[[1 2 3]
 [4 5 6]]
flatten: [1 2 3 4 5 6]
flatten (modified): [100 2 3 4 5 6]
Original array after modification:
[[1 2 3]
 [4 5 6]]

メモリレイアウトの指定 (order)

order引数を使うと、多次元配列を1次元化する際のメモリ上の配置順序を指定できます。 'C'(C言語スタイル)を選ぶと行優先、'F'(Fortranスタイル)を選ぶと列優先になります。デフォルトは'C'です。

arr2d = np.array([[1, 2, 3], [4, 5, 6]])

arr1d_flatten_c = arr2d.flatten(order='C')  # Cスタイル(行優先) デフォルト
arr1d_flatten_f = arr2d.flatten(order='F')  # Fortranスタイル(列優先)

print(f"flatten (order='C'): {arr1d_flatten_c}")
print(f"flatten (order='F'): {arr1d_flatten_f}")

出力

flatten (order='C'): [1 2 3 4 5 6]
flatten (order='F'): [1 4 2 5 3 6]

2. ravel の概要と基本的な使い方

概要

ndarray.ravel()は、多次元配列を1次元配列として返します。flattenとは異なり、ravelは可能な限り元の配列のビューを返そうとします。(ビューとは、元の配列のデータを共有する別の配列のことです。ビューを変更すると、元の配列も変更されます。) ただし、メモリレイアウトによってはコピーが返される場合もあります。

基本的な使い方

import numpy as np

# 2次元配列を作成
arr2d = np.array([[1, 2, 3], [4, 5, 6]])
print(f"Original array:\n{arr2d}")

# ravelを使って1次元化 (可能な限りビューが返される)
arr1d_ravel = arr2d.ravel()
print(f"ravel: {arr1d_ravel}")

# ravelで作成した配列(ビュー)を変更すると、元の配列も変更される
arr1d_ravel[0] = 100
print(f"ravel (modified): {arr1d_ravel}")
print(f"Original array after modification:\n{arr2d}")

出力

Original array:
[[1 2 3]
 [4 5 6]]
ravel: [1 2 3 4 5 6]
ravel (modified): [100 2 3 4 5 6]
Original array after modification:
[[100 2 3]
 [4 5 6]]

上記の例では、arr1d_ravelarr2d のビューなので、arr1d_ravel への変更が arr2d にも反映されています。

メモリレイアウトの指定 (order)

flattenと同様に、order引数でメモリレイアウトを指定できます。

arr2d = np.array([[1, 2, 3], [4, 5, 6]])

arr1d_ravel_c = arr2d.ravel(order='C')  # Cスタイル(行優先) デフォルト
arr1d_ravel_f = arr2d.ravel(order='F')  # Fortranスタイル(列優先)

print(f"ravel (order='C'): {arr1d_ravel_c}")
print(f"ravel (order='F'): {arr1d_ravel_f}")

出力

ravel (order='C'): [1 2 3 4 5 6]
ravel (order='F'): [1 4 2 5 3 6]

order='F'を指定した場合や、配列がFortran順序で連続している場合など、ravelはビューではなくコピーを返すことがあります。 ビューが欲しいのかコピーが欲しいのか明確でない場合は、ravelの戻り値に対してbase属性をチェックすることで、それがビューなのかコピーなのかを判別できます。ビューであればbase属性は元の配列を指し、コピーであればNoneを返します。

arr = np.array([[1, 2], [3, 4]], order='F')
arr1d_ravel = arr.ravel()
print(arr1d_ravel.base is arr) # False コピーが返された
print(arr1d_ravel.base is None) # False コピーの場合でもNoneとは限らない

arr = np.array([[1, 2], [3, 4]], order='C')
arr1d_ravel = arr.ravel()
print(arr1d_ravel.base is arr) # True ビューが返された

flattenravel の違い

機能 flatten ravel
戻り値 常にコピーを返す 可能な限りビューを返す(メモリレイアウトによってはコピーを返す)
元の配列への影響 元の配列は変更されない ビューが返された場合、ビューの変更は元の配列に影響する
メモリ使用量 コピーを作成するため、メモリ使用量が増える可能性がある ビューの場合はメモリ使用量が少ない。ただし、コピーが作成される場合もある
速度 コピーの作成に時間がかかる場合がある 一般的にflattenより高速(特に大きな配列の場合)
order引数 'C', 'F', 'A', 'K' 'C', 'F', 'A', 'K'

flattenravel の使い分け

  • flatten
    • 元の配列を変更したくない場合
    • 1次元化された配列のコピーが必要な場合
  • ravel
    • メモリ効率を優先する場合(不要なコピーを避けたい場合)
    • 1次元化された配列を通じて、元の配列も変更したい場合
    • 速度が重要な場合(特に大きな配列)

まとめ

flattenravelは、どちらもNumPy配列を1次元化するメソッドですが、flattenは常にコピーを返し、ravelは可能な限りビューを返します(ただし、メモリレイアウトによってはコピーを返すこともあります)。メモリ効率や処理速度を意識して使い分けることが重要です。元の配列を変更したくない場合はflatten、変更したい場合やメモリ効率を優先する場合はravelを使用します。

[PR]

現場で使える!NumPyデータ処理入門 機械学習・データサイエンスで役立つ高速処理手法 (AI & TECHNOLOGY) [ 吉田 拓真 ]

RとPythonで学ぶ[実践的]データサイエンス&機械学習【増補改訂版】 [ 有賀友紀、大橋俊介 ]

Pythonプログラミングパーフェクトマスター[最新Visual Studio Code対応 第4版] [ 金城俊哉 ]




以上の内容はhttps://pydocument.hatenablog.com/entry/2025/02/22/190329より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14