Visualizza su un array numpy?


90

Ho un numpyarray 2D . C'è un modo per creare una vista su di esso che includa le prime krighe e tutte le colonne?

Il punto è evitare di copiare i dati sottostanti (l'array è così grande che non è possibile effettuare copie parziali).

Risposte:


226

Certo, indicizzalo come faresti normalmente. Ad esempio, y = x[:k, :] questo restituirà una vista nell'array originale. Nessun dato verrà copiato e gli eventuali aggiornamenti apportati ysi rifletteranno su xe viceversa.


Modificare:

Di solito lavoro con array 3D> 10 GB di uint8, quindi mi preoccupo molto di questo ... Numpy può essere molto efficiente nella gestione della memoria se si tengono a mente alcune cose. Ecco alcuni suggerimenti su come evitare di creare copie di array in memoria:

Usa +=, -=, *=, ecc per evitare di fare una copia della matrice. Ad esempio x += 10, modificherà l'array in posizione, mentre x = x + 10ne farà una copia e lo modificherà. (inoltre, dai un'occhiata a numexpr )

Se vuoi fare una copia con x = x + 10, tieni presente che x = x + 10.0verrà xeseguito automaticamente l'up-cast su un array a virgola mobile, se non lo era già. Tuttavia, x += 10.0dove xè un array intero, verrà invece 10.0eseguito il downcast di un valore int della stessa precisione dell'array.

Inoltre, molte funzioni numpy accettano un outparametro, quindi puoi fare cose come np.abs(x, x)prendere il valore assoluto di xsul posto.


Come seconda modifica, ecco alcuni altri suggerimenti su visualizzazioni e copie con array numpy:

A differenza degli elenchi di Python, y = x[:]non restituisce una copia, restituisce una visualizzazione. Se vuoi una copia (che, ovviamente, raddoppierà la quantità di memoria che stai utilizzando) usay = x.copy()

Sentirai spesso parlare di "indicizzazione di fantasia" di array numpy. Usare un elenco (o un array di numeri interi) come indice è "indicizzazione fantasia". Può essere molto utile, ma copia i dati.

Ad esempio: y = x[[0, 1, 2], :]restituisce una copia, mentre y = x[:3,:]restituisce una visualizzazione.

Anche un'indicizzazione veramente folle come x[4:100:5, :-10:-1, None]è l' indicizzazione "normale" e restituirà una vista, quindi non aver paura di usare tutti i tipi di trucchi di slicing su array di grandi dimensioni.

x.astype(<dtype>)restituirà una copia dei dati come nuovo tipo, mentre x.view(<dtype>)restituirà una visualizzazione.

Fai attenzione, tuttavia ... È estremamente potente e utile, ma devi capire come i dati sottostanti vengono archiviati in memoria. Se hai un array di float e li visualizzi come int, (o viceversa) numpy interpreterà i bit sottostanti dell'array come int.

Ad esempio, questo significa che 1.0come un float a 64 bit su un sistema little-endian sarà 4607182418800017408visto come un int a 64 bit e un array di [ 0, 0, 0, 0, 0, 0, 240, 63]se visto come uint8. Questo è davvero bello quando hai bisogno di fare qualche giro di bit su array di grandi dimensioni, però ... Hai un controllo di basso livello su come viene interpretato il buffer di memoria.


Grazie per i suggerimenti molto carini! Stavo leggendo la guida utente di Numpy e sono confuso perché x[np.array([1, 1, 3, 1])] += 1modificato x. Ora capito!
tnq177

bei consigli! Ho un'altra domanda. Come dimostrare che numpy non attiva una copia ma solo una vista? id () di python sembra incapace di questo.
wuhaochi

3
@wuhaochi Se bè una visione di a, allora b.base is asarà True. Una copia (di qualsiasi matrice) avrà semprearr_copy.base is None
Jürg Merlin Spaak
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.