Numpy에서 Flatten과 Ravel 함수의 차이점은 무엇입니까?


292
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]

두 함수 모두 같은 목록을 반환합니다. 그런 다음 동일한 작업을 수행하는 두 가지 기능이 필요합니다.


14
Ravel은 일반적으로 뷰를 기존 배열로 반환합니다 (때로는 복사본을 반환 함). Flatten은 새로운 배열을 반환합니다.
Alex


1
다음 은 미묘한 차이에 대한 실용적인 데모입니다.
prosti

그렇다면 누군가 배열을 평평하게하는 것이 더 좋을 때와 그것을 어슬렁 거리는 경우를 예를 들어 줄 수 있습니까?
Aleksandar

답변:


371

현재 API는 다음과 같습니다.

  • flatten 항상 사본을 반환합니다.
  • ravel가능할 때마다 원래 배열의 뷰를 반환합니다. 이것은 인쇄 된 결과물에는 보이지 않지만, ravel이 반환 한 배열을 수정하면 원래 배열의 항목이 수정 될 수 있습니다. flatten에서 반환 된 배열의 항목을 수정하면 이런 일이 발생하지 않습니다. 메모리가 복사되지 않으므로 ravel이 더 빠를 수 있지만 반환되는 배열을 수정하는 데 더주의해야합니다.
  • reshape((-1,)) 배열의 보폭이 항상 연속 배열을 얻지 못한다고해도 배열의 보폭이 허용 할 때마다 뷰를 얻습니다.

30
NumPy 개발자가 매개 변수 copy = [True, False]를 사용하여 하나의 함수를 고수하지 않은 이유는 무엇입니까?
Franck Dernoncourt

41
Backcompat는 때때로 이와 같은 이상한 일이 발생하도록 보장합니다. 예를 들어, 최근 (1.10) numpy 개발자는 ravel이 인접한 배열 (C 확장을 작성할 때 매우 중요한 속성)을 반환한다는 이전의 암시 적 보증을 추가 했으므로 이제 API는 피할 a.flatten()수 있도록 사본을 얻는 것입니다. a.ravel()대부분의 사본이지만 반환 된 배열이 연속적임을 보장하고 배열 a.reshape((-1,))의 보폭이 허용 될 때마다 실제로보기를 얻는 것은 항상 인접한 배열을 얻지 못한다는 것을 의미합니다.
IanH

4
@Hossein IanH는 다음과 같이 설명했습니다. ravel연속 배열을 보장하므로 뷰를 반환한다고 보장하지 않습니다. reshape항상 뷰를 반환하므로 연속 배열을 반환한다고 보장 할 수 없습니다.
17:19에 iled

4
@Hossein 완전히 새로운 질문이 될 것입니다. 간단히 말해서, 인접한 메모리 공간을 읽고 쓰는 것이 훨씬 빠릅니다. 여기에 대한 몇 가지 질문과 답변이 있습니다 ( 여기 좋은 예 ). 추가 질문이 있으면 언제든지 새로운 질문을여십시오.
iled

2
reshape(-1)에 해당합니다reshape((-1,))
톰 댄 폴

53

여기 에 설명 된 주요 차이점은 다음과 같습니다.

  • flatten 은 ndarray 객체의 메서드이므로 실제 numpy 배열에 대해서만 호출 할 수 있습니다.

  • ravel 는 라이브러리 수준 함수이므로 성공적으로 구문 분석 할 수있는 모든 개체에서 호출 할 수 있습니다.

예를 들어 ravelndarray 목록에서 작동하지만 flatten해당 유형의 객체에는 사용할 수 없습니다.

@IanH는 또한 그의 대답에서 메모리 처리와 중요한 차이점을 지적합니다.


4
목록에서 작업 라벨 (약 그 정보를 들으) ndarray
javadba

뿐만 아니라 배열의 목록뿐만 아니라 :리스트의리스트
timtody

15

함수에 대한 올바른 네임 스페이스는 다음과 같습니다.

두 함수 모두 새로운 메모리 구조를 가리키는 평평한 1D 배열을 반환합니다.

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

위의 예에서 :

  • 결과의 메모리 위치가 다릅니다.
  • 결과는 동일하게 보입니다
  • 납작 해지다
  • 라벨은보기를 반환합니다.

어떤 것이 사본인지 어떻게 확인합니까? 의 .base속성을 사용합니다 ndarray. 뷰인 경우 기본은 원래 배열이됩니다. 사본 인 경우 기준은입니다 None.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.