2016-07-13 29 views
8

Qual è la differenza tra quanto segue?numpy difference between flat and ravel()

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

A parte il fatto che flat restituisce un iteratore invece di una lista, sembrano essere la stessa, poiché entrambi alterano la matrice originale in luogo (questo è in contrasto con flatten(), che restituisce una copia di l'array). Quindi, c'è qualche altra differenza significativa tra flat e ravel()? Altrimenti, quando sarebbe utile usarne uno invece dell'altro?

+0

'np.array (arr.flat)' dà qualcosa di più vicino (forse identico) a 'np.ravel (x)'. – hpaulj

risposta

8

flat è un iteratore. È un oggetto separato che capita semplicemente di dare accesso agli elementi dell'array tramite l'indicizzazione. Lo scopo principale è quello di essere utilizzato nei loop e nelle espressioni di comprensione. L'ordine che dà è lo stesso di quello che generalmente ottieni da ravel.

A differenza del risultato di ravel, flat non è un ndarray, quindi non può fare molto oltre all'indicizzazione dell'array e iterando su di esso. Si noti che è necessario chiamare list per visualizzare il contenuto dell'iteratore. Ad esempio, arr.flat.min() non riuscirebbe con un AttributeError, mentre arr.ravel().min() darebbe lo stesso risultato di arr.min().

Poiché numpy fornisce così tante operazioni che non richiedono la scrittura di cicli espliciti, ndarray.flat e gli iteratori in generale, vengono utilizzati raramente rispetto a ndarray.ravel().

Detto questo, ci sono situazioni in cui è preferibile un iteratore. Se il tuo array è abbastanza grande e stai cercando di ispezionare tutti gli elementi uno per uno, un iteratore funzionerebbe bene. Ciò è particolarmente vero se si dispone di qualcosa come un array mappato in memoria che viene caricato in porzioni.

+1

In particolare 'flat' produce un oggetto di tipo' np.flatiter' (vedi i suoi documenti). Inoltre è implementato come un attributo dell'array, non un metodo o funzione. – hpaulj

+0

@hpaulj Tecnicamente 'flat' è una proprietà di' ndarray', il che significa che è fondamentalmente un metodo no-arg a cui si accede come attributo, ma che in realtà restituisce una nuova istanza ogni volta che si accede. –

+1

'flat' (lungo attributi come' shape') sono definiti nel codice 'numpy'' c', e in realtà non usano il meccanismo 'property' di Python':' numpy/core/src/multiarray/getset.c' . Funzionalmente sembrano simili. – hpaulj