numpy.ravelで1次元配列に変換する方法(flattenと比較)

numpy.ravel で配列を1次元配列に変換する

numpy.ravel は配列を1次元化するために使用します。ravelは英語で「ほぐす」という意味で、この場合多次元配列をほぐして1次元配列にするという意味です。

numpy.flatten という関数も同様に配列を1次元化するために使用できます。両者の違いは、配列のビュー(同じ参照)で作成するか、コピーで作成するかの違いです。

flattenは必ずコピーを作成しますが、numpy.ravel は基本的にコピーを作成しません。そのため、メモリが節約され高速に動作することが期待できます。

numpy.ravel関数の使い方

例えば、3×4の2次元配列を1次元配列に変換する場合は、以下のようにします。

import numpy as np

a = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
])

# numpy.ravelで1次元配列に変換
b = np.ravel(a)

# ndarray.ravelも定義されているので次のようにも書ける
# b = a.ravel()

print(a)
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]
print(b)
# [1 2 3 4 5 6 7 8 9]

2次元配列のデータが1次元配列に展開されていることが確認できます。ほかの関数と同じく ravel はndarrayにも定義されているので a.ravel() の形でも呼び出すことができます。

numpy.ravel関数のパラメータ

numpy.ravel(a, order='C')

パラメータ 説明
a array_like 変換元となる配列(ndarrayやPythonのリストなど)を指定します。
newshape int, タプル 新しい形状(shape)を指定します。元の形状と互換性がなければなりません。整数値の場合、そのサイズの1次元配列となります。
order string 省略可能。デフォルトは'C'。‘C','F','A','K' から指定します。'C'の場合、列方向優先で要素を読み取ります。'F'の場合、行方向優先で要素を読み取ります。'A'の場合、配列がFortanの順序でメモリに並んでいるときにその順序で要素を読み取ります。'K'の場合、メモリ内の発生順序で要素を読み取ります。

return値として、引数の配列の値を持った1次元配列(ndarray)を返します。コピーは必要な場合のみ作成されます。

使い方は引数で配列を指定するだけです。orderは1次元配列としてデータを格納する順序に影響します。

import numpy as np

# 2×3の2次元配列
a = np.arange(6).reshape((2, 3), order="C")

b = np.ravel(a) # order省略だと'C'
c = np.ravel(a, order="F")
d = np.ravel(a, order="K")
e = np.ravel(a, order="A")

# Order="F"だと行方向から読み出されている
print(b) # order="C" [0 1 2 3 4 5]
print(c) # order="F" [0 3 1 4 2 5]
print(d) # order="K" [0 1 2 3 4 5]
print(e) # order="A" [0 1 2 3 4 5]

# もとがFの並びだと
f = np.arange(6).reshape((2, 3), order="F")
print(f.ravel(order="C")) # [0 1 2 3 4 5]
print(f.ravel(order="F")) # [0 2 4 1 3 5]
print(f.ravel(order="K")) # [0 1 2 3 4 5]
print(f.ravel(order="A")) # [0 1 2 3 4 5]

上記例では order を変更して試してみました。読み出される順番が変わるので得られる1次元配列の値の順番が指定によって変わっているのが確認できます。

ndarray.ravel のパラメータは a を指定しなくてよいので order 一つだけです。

flatten関数との違い

ndarray.flatten も ravel関数と同様に、1次元化した配列を返してくれる関数ですが、こちらは必ず配列のコピーを生成します。コピーが必要な場面ではこちらの使用が必要になります。

また、flattenはndarrayの方にしか定義されていません。np.flattenとしても存在しない関数のため動作しません。

最後に両者のパフォーマンスを比較して終わります。言うまでもなく、コピーを生成する ndarray.flatten より ndarray.ravel のほうが高速です。

まとめ

以上。

参考URL