
È possibile utilizzare l’attributo base per se l’array NumPy numpy.ndarray è una vista o una copia. Inoltre, np.shares_memory() può essere utilizzato per consentire se due array devono essere la memoria.
Questo articolo descrive quanto segue:
- Visualizza e copia numpy.ndarray
- Esempio di creazione di una vista
- Esempio di creazione di una copia
- copy() e view()
- Determina se visualizzare o ottenere:
base attribute
- Determina se la memoria è condivisa:
np.shares_memory()
- Utilizzo di base
- np.may_share_memory()
La versione di NumPy nel codice di esempio seguente è 1.16.4. Si noti che versioni diverse potrebbero comportarsi in modo diverso.
Visualizza e copia numpy.ndarray
Esistono due tipi di numpy.ndarray: recensioni e copy.
Quando si crea un altro oggetto da matrice da un oggetto matrice, l’oggetto che condivide la memoria con l’oggetto originale (si riferisce a parte oa tutta la memoria dell’oggetto originale) viene chiamato vista.
D’altra parte, un oggetto che alloca memoria separatamente dall’oggetto originale viene copiato.
Esempio di creazione di una vista
Ad esempio, le sezioni si creano viste.
import numpy as np
a_2d = np.arange(12).reshape(3, 4)
print(a_2d)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
a_slice = a_2d[:2, :2]
print(a_slice)
# [[0 1]
# [4 5]]
L’oggetto originale e la vista si appartiene alla stessa memoria, quindi la modifica del valore di un elemento in un oggetto cambia il valore nell’altro.
a_slice[0, 0] = 100
print(a_slice)
# [[100 1]
# [ 4 5]]
print(a_2d)
# [[100 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
a_2d[0, 0] = 0
print(a_2d)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(a_slice)
# [[0 1]
# [4 5]]
Oltre alle sezioni, alcune funzioni e metodi, come reshape(), che verranno utilizzati nell’esempio sezione successiva, restituiscono una vista.
Esempio di creazione di una copia
L’indicizzazione di fantasia crea copie.
a_fancy_index = a_2d[[0, 1]]
print(a_fancy_index)
# [[0 1 2 3]
# [4 5 6 7]]
Perché non condividere la memoria, la modifica del valore di un oggetto non cambia il valore dell’altro.
a_fancy_index[0, 0] = 100
print(a_fancy_index)
# [[100 1 2 3]
# [ 4 5 6 7]]
print(a_2d)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
copy() e view()
È possibile utilizzare copy() per creare una copia di un oggetto array.
È anche possibile creare una copia della vista.
a_slice_copy = a_2d[:2, :2].copy()
print(a_slice_copy)
# [[0 1]
# [4 5]]
La modifica del valore di un elemento di un oggetto non modifica il valore dell’altro.
a_slice_copy[0, 0] = 100
print(a_slice_copy)
# [[100 1]
# [ 4 5]]
print(a_2d)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
C’è anche un metodo chiamato view().
Tuttavia, ad esempio, la chiamata a view() da un oggetto creato da un’indicizzazione di fantasia restituirà solo la vista di una copia, non la vista dell’oggetto originale.
Determina se visualizzare o ottenere:base attribute
Usa l’attributo di base per se numpy.ndarray è una vista o una copia (strettamente una vista o meno).
Se numpy.ndarray è una vista, l’attributo base restituisce l’originale numpy.ndarray.
Prendi reshape(), che porta una vista il più possibile, come esempio.
a = np.arange(10)
print(a)
# [0 1 2 3 4 5 6 7 8 9]
a_0 = a[:6]
print(a_0)
# [0 1 2 3 4 5]
a_1 = a_0.reshape(2, 3)
print(a_1)
# [[0 1 2]
# [3 4 5]]
print(a_0.base)
# [0 1 2 3 4 5 6 7 8 9]
print(a_1.base)
# [0 1 2 3 4 5 6 7 8 9]
L’attributo di base della copia o dell’originale numpy.ndarray (un numpy.ndarray appena creato che non è né una copia né una vista) è Nessuno.
a_copy = a.copy()
print(a_copy)
# [0 1 2 3 4 5 6 7 8 9]
print(a_copy.base)
# None
print(a.base)
# None
È possibile utilizzare l’operatore è per l’attributo di base Nessuno per utilizzare se si tratta di una vista o meno.
print(a_0.base is None)
# False
print(a_copy.base is None)
# True
print(a.base is None)
# True
Puoi anche vedere che vuoi la memoria confrontando l’attributo di base della vista con l’originale numpy.ndarray o confrontando tra loro gli attributi di base della vista.
print(a_0.base is a)
# True
print(a_0.base is a_1.base)
# True
Il seguente np.shares_memory() è conveniente per se la memoria è condivisa.
Determina se la memoria è condivisa:np.shares_memory()
Se i due array devono essere la memoria può essere determinato np.shares_memory().
Utilizzo di base
Specificare numpy.ndarray in np.shares_memory(). True viene restituito se tali array contengono la memoria.
a = np.arange(6)
print(a)
# [0 1 2 3 4 5]
a_reshape = a.reshape(2, 3)
print(a_reshape)
# [[0 1 2]
# [3 4 5]]
print(np.shares_memory(a, a_reshape))
# True
Se si specificano due viste generate dal comune numpy.ndarray, viene restituito anche True.
a_slice = a[2:5]
print(a_slice)
# [2 3 4]
print(np.shares_memory(a_reshape, a_slice))
# True
In caso di copia, False viene restituito.
a_reshape_copy = a.reshape(2, 3).copy()
print(a_reshape_copy)
# [[0 1 2]
# [3 4 5]]
print(np.shares_memory(a, a_reshape_copy))
# False
np.may_share_memory()
C’è anche una funzione simile a np.shares_memory() chiamata np.may_share_memory().
np.may_share_memory() è meno rigido di np.shares_memory(), come puoi vedere dal fatto che il nome della funzione contiene maggio.
np.may_share_memory() determina solo se gli intervalli di indirizzi di memoria si sovrappongono, non considera se sono presenti elementi fanno che riferimento alla stessa memoria.
Ad esempio, nel seguente, le due sezioni sono la vista di num.ndarray e si verificano all’intervallo di sovrapposizione, ma ogni elemento stesso fa riferimento a una diversa memoria.
a = np.arange(10)
print(a)
# [0 1 2 3 4 5 6 7 8 9]
a_0 = a[::2]
print(a_0)
# [0 2 4 6 8]
a_1 = a[1::2]
print(a_1)
# [1 3 5 7 9]
np.shares_memory() restituisce False per un giudizio rigoroso, ma np.may_share_memory() restituisce True.
print(np.shares_memory(a_0, a_1))
# False
print(np.may_share_memory(a_0, a_1))
# True
Nell’esempio seguente, np.may_share_memory() aggiunge False perché le due sezioni sono la prima metà e la seconda metà del numpy.ndarray originale e gli non si sovrappongono.
a_2 = a[:5]
print(a_2)
# [0 1 2 3 4]
a_3 = a[5:]
print(a_3)
# [5 6 7 8 9]
print(np.shares_memory(a_2, a_3))
# False
print(np.may_share_memory(a_2, a_3))
# False
Il tempo di elaborazione è più lungo per np.shares_memory(), il che esprime un giudizio rigoroso. Si noti che il codice seguente utilizza il comando magico di Jupyter Notebook %%timeit e non viene misurato quando come eseguire script Python.
%%timeit
np.shares_memory(a_0, a_1)
# 839 ns ± 53.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%%timeit
np.may_share_memory(a_0, a_1)
# 275 ns ± 5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
per np.may_share_memory() possa restituire True per errore quando ogni elemento non condivide la memoria, non ripete False per errore quando la memoria è condivisa.