Ho un numpy
array 2D . C'è un modo per creare una vista su di esso che includa le prime k
righe e tutte le colonne?
Il punto è evitare di copiare i dati sottostanti (l'array è così grande che non è possibile effettuare copie parziali).
Risposte:
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 y
si rifletteranno su x
e 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 + 10
ne 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.0
verrà x
eseguito automaticamente l'up-cast su un array a virgola mobile, se non lo era già. Tuttavia, x += 10.0
dove x
è un array intero, verrà invece 10.0
eseguito il downcast di un valore int della stessa precisione dell'array.
Inoltre, molte funzioni numpy accettano un out
parametro, quindi puoi fare cose come np.abs(x, x)
prendere il valore assoluto di x
sul 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.0
come un float a 64 bit su un sistema little-endian sarà 4607182418800017408
visto 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.
b
è una visione di a
, allora b.base is a
sarà True
. Una copia (di qualsiasi matrice) avrà semprearr_copy.base is None
x[np.array([1, 1, 3, 1])] += 1
modificatox
. Ora capito!