web-dev-qa-db-ja.com

numpyにおけるflatten関数とravel関数の違いは何ですか?

import numpy as np
y = np.array(((1,2,3),(4,5,6),(7,8,9)))
OUTPUT:
print(y.flatten())
[1   2   3   4   5   6   7   8   9]
print(y.ravel())
[1   2   3   4   5   6   7   8   9]

どちらの関数も同じリストを返します。それでは、同じ仕事をする2つの異なる機能の必要性があります。

231
DEEPAK YADAV

現在のAPIは以下のとおりです。

  • flatten は常にコピーを返します。
  • ravel は可能な限り元の配列のビューを返します。これは印刷出力には表示されませんが、ravelによって返された配列を変更すると、元の配列のエントリが変更される可能性があります。 flattenから返された配列のエントリを修正しても、これは起こりません。メモリがコピーされないのでravelはしばしば速くなりますが、返される配列を変更することについてもっと注意を払う必要があります。
  • reshape((-1,)) 配列のストライドが許可するときはいつでもビューを取得します。たとえそれが連続した配列を取得するとは限らないとしてもです。
307
IanH

説明したように ここ 重要な違いはflattenはndarrayオブジェクトのメソッドであり、したがって真のテンキー配列に対してのみ呼び出せることです。対照的に、ravel()はライブラリレベルの関数であり、したがって、解析に成功した任意のオブジェクトに対して呼び出すことができます。たとえばravel()はndarraysのリストに対して機能しますが、flattenはそのタイプのオブジェクトには使用できません。

@IanHはまた、彼の答えの中でメモリ処理との重要な違いを指摘しています。

32
Bryan P

これが関数の正しい名前空間です。

どちらの関数も、新しいメモリ構造を指す平坦化された1次元配列を返します。

import numpy
a = numpy.array([[1,2],[3,4]])

r = numpy.ravel(a)
f = numpy.ndarray.flatten(a)  

print(id(a))
print(id(r))
print(id(f))

print(r)
print(f)

print("\nbase r:", r.base)
print("\nbase f:", f.base)

---returns---
140541099429760
140541099471056
140541099473216

[1 2 3 4]
[1 2 3 4]

base r: [[1 2]
 [3 4]]

base f: None

上の例では:

  • 結果のメモリ位置が異なります。
  • 結果は同じように見えます
  • flattenはコピーを返します
  • ravelはビューを返します。

コピーかどうか、どうやって確認しますか。 ndarray.base属性を使用する。ビューの場合、ベースは元の配列になります。コピーの場合、ベースはNoneになります。

8
prosti