2016-07-13 40 views
8

以下幾點有什麼區別?flat和ravel之間的numpy差異()

>>> import numpy as np 
>>> arr = np.array([[[ 0, 1, 2], 
...     [ 10, 12, 13]], 
...     [[100, 101, 102], 
...     [110, 112, 113]]]) 
>>> arr 
array([[[ 0, 1, 2], 
     [ 10, 12, 13]], 
     [[100, 101, 102], 
     [110, 112, 113]]]) 
>>> arr.ravel() 
array([ 0, 1, 2, 10, 12, 13, 100, 101, 102, 110, 112, 113]) 
>>> arr.ravel()[0] = -1 
>>> arr 
array([[[ -1, 1, 2], 
     [ 10, 12, 13]], 
     [[100, 101, 102], 
     [110, 112, 113]]]) 
>>> list(arr.flat) 
[-1, 1, 2, 10, 12, 13, 100, 101, 102, 110, 112, 113] 
>>> arr.flat[0] = 99 
>>> arr 
array([[[ 99, 1, 2], 
     [ 10, 12, 13]], 
     [[100, 101, 102], 
     [110, 112, 113]]]) 

除了一個事實,即flat返回一個迭代器而不是列表,它們似乎是相同的,因爲他們都改變代替原來陣列(這是對比flatten(),它返回的副本該陣列)。那麼,flatravel()之間是否還有其他重要的區別?如果不是,那麼使用一個而不是另一個會有什麼用處?

+0

'np.array(arr.flat)'給出了更接近np.ravel(x)'的東西(可能是相同的)。 – hpaulj

回答

8

flat是一個迭代器。它是一個單獨的對象,恰好通過索引來訪問數組元素。它的主要目的是用於循環和理解表達式。它給出的順序與您通常從ravel獲得的順序相同。

ravel的結果不同,flat不是ndarray,所以除了索引數組和迭代它之外,它不能做很多事情。注意你必須調用list來查看迭代器的內容。例如,arr.flat.min()將以AttributeError失敗,而arr.ravel().min()會得出與arr.min()相同的結果。

由於numpy提供了很多不需要顯式循環寫入的操作,因此和迭代器通常很少使用,與ndarray.ravel()相比很少使用。

這就是說,有些情況下迭代器是可取的。如果你的數組足夠大,並且你試圖逐個檢查所有的元素,那麼迭代器就能正常工作。如果你有像內存映射數組那樣被加載的東西,這是尤其如此。

+1

具體而言'flat'產生一個'np.flatiter'類型的對象(參見文檔)。它也作爲數組的屬性實現,而不是方法或函數。 – hpaulj

+0

@hpaulj技術上'flat'是'ndarray'的一個屬性,這意味着它基本上是一個作爲屬性訪問的無參數方法,但每次訪問時都會返回一個新實例。 –

+1

'flat'(沿着類似'shape'的屬性)在'numpy''''代碼中定義,並且實際上並沒有使用Python的'property'機制:'numpy/core/src/multiarray/getset.c' 。在功能上它們看起來相似。 – hpaulj