Ricerca…
introduzione
Gli array N-dimensionali o ndarrays
sono gli oggetti principali di numpy utilizzati per memorizzare elementi dello stesso tipo di dati. Forniscono una struttura dati efficiente che è superiore agli ordinari array Python.
Osservazioni
Ogni volta che è possibile esprimere operazioni sui dati in termini di matrici e operazioni vettoriali. Le operazioni vettoriali vengono eseguite molto più velocemente dell'equivalente per i loop
Crea una matrice
Matrice vuota
np.empty((2,3))
Si noti che in questo caso, i valori in questo array non sono impostati. Questo modo di creare un array è quindi utile solo se l'array viene riempito più avanti nel codice.
Da una lista
np.array([0,1,2,3])
# Out: array([0, 1, 2, 3])
Crea un intervallo
np.arange(4)
# Out: array([0, 1, 2, 3])
Crea zeri
np.zeros((3,2))
# Out:
# array([[ 0., 0.],
# [ 0., 0.],
# [ 0., 0.]])
Crea uno
np.ones((3,2))
# Out:
# array([[ 1., 1.],
# [ 1., 1.],
# [ 1., 1.]])
Crea elementi di array con spaziatura lineare
np.linspace(0,1,21)
# Out:
# array([ 0. , 0.05, 0.1 , 0.15, 0.2 , 0.25, 0.3 , 0.35, 0.4 ,
# 0.45, 0.5 , 0.55, 0.6 , 0.65, 0.7 , 0.75, 0.8 , 0.85,
# 0.9 , 0.95, 1. ])
Crea elementi di array con spazi logaritmici
np.logspace(-2,2,5)
# Out:
# array([ 1.00000000e-02, 1.00000000e-01, 1.00000000e+00,
# 1.00000000e+01, 1.00000000e+02])
Crea una matrice da una determinata funzione
np.fromfunction(lambda i: i**2, (5,))
# Out:
# array([ 0., 1., 4., 9., 16.])
np.fromfunction(lambda i,j: i**2, (3,3))
# Out:
# array([[ 0., 0., 0.],
# [ 1., 1., 1.],
# [ 4., 4., 4.]])
Operatori di array
x = np.arange(4)
x
#Out:array([0, 1, 2, 3])
l'aggiunta scalare è elementare
x+10
#Out: array([10, 11, 12, 13])
la moltiplicazione scalare è elementare
x*2
#Out: array([0, 2, 4, 6])
l'aggiunta dell'array è un elemento saggio
x+x
#Out: array([0, 2, 4, 6])
la moltiplicazione degli array è elementare
x*x
#Out: array([0, 1, 4, 9])
il prodotto punto (o più in generale la moltiplicazione della matrice) viene eseguito con una funzione
x.dot(x)
#Out: 14
In Python 3.5, l'operatore @
stato aggiunto come operatore infisso per la moltiplicazione della matrice
x = np.diag(np.arange(4))
print(x)
'''
Out: array([[0, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 2, 0],
[0, 0, 0, 3]])
'''
print(x@x)
print(x)
'''
Out: array([[0, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 4, 0],
[0, 0, 0, 9]])
'''
Aggiungi Restituisce la copia con i valori aggiunti. NON sul posto.
#np.append(array, values_to_append, axis=None)
x = np.array([0,1,2,3,4])
np.append(x, [5,6,7,8,9])
# Out: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
x
# Out: array([0, 1, 2, 3, 4])
y = np.append(x, [5,6,7,8,9])
y
# Out: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Hstack . Stack orizzontale. (pila di colonne)
vstack . Pila verticale. (pila di file)
# np.hstack(tup), np.vstack(tup)
x = np.array([0,0,0])
y = np.array([1,1,1])
z = np.array([2,2,2])
np.hstack(x,y,z)
# Out: array([0, 0, 0, 1, 1, 1, 2, 2, 2])
np.vstack(x,y,z)
# Out: array([[0, 0, 0],
# [1, 1, 1],
# [2, 2, 2]])
Array Access
La sintassi Slice è i:j:k
dove i
è l'indice iniziale (incluso), j
è l'indice di arresto (esclusivo) e k
è la dimensione del passo. Come altre strutture di dati python, il primo elemento ha un indice di 0:
x = np.arange(10)
x[0]
# Out: 0
x[0:4]
# Out: array([0, 1, 2, 3])
x[0:4:2]
# Out:array([0, 2])
I valori negativi contano dalla fine dell'array. -1
quindi accede all'ultimo elemento di un array:
x[-1]
# Out: 9
x[-1:0:-1]
# Out: array([9, 8, 7, 6, 5, 4, 3, 2, 1])
È possibile accedere agli array multidimensionali specificando ogni dimensione separata da virgole. Si applicano tutte le regole precedenti.
x = np.arange(16).reshape((4,4))
x
# Out:
# array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11],
# [12, 13, 14, 15]])
x[1,1]
# Out: 5
x[0:3,0]
# Out: array([0, 4, 8])
x[0:3, 0:3]
# Out:
# array([[ 0, 1, 2],
# [ 4, 5, 6],
# [ 8, 9, 10]])
x[0:3:2, 0:3:2]
# Out:
# array([[ 0, 2],
# [ 8, 10]])
Trasposizione di un array
arr = np.arange(10).reshape(2, 5)
Utilizzando il metodo .transpose
:
arr.transpose()
# Out:
# array([[0, 5],
# [1, 6],
# [2, 7],
# [3, 8],
# [4, 9]])
Metodo .T
:
arr.T
# Out:
# array([[0, 5],
# [1, 6],
# [2, 7],
# [3, 8],
# [4, 9]])
O np.transpose
:
np.transpose(arr)
# Out:
# array([[0, 5],
# [1, 6],
# [2, 7],
# [3, 8],
# [4, 9]])
Nel caso di un array bidimensionale, questo è equivalente a una trasposizione matrice standard (come illustrato sopra). Nel caso n-dimensionale, è possibile specificare una permutazione degli assi dell'array. Per impostazione predefinita, questo inverte array.shape
:
a = np.arange(12).reshape((3,2,2))
a.transpose() # equivalent to a.transpose(2,1,0)
# Out:
# array([[[ 0, 4, 8],
# [ 2, 6, 10]],
#
# [[ 1, 5, 9],
# [ 3, 7, 11]]])
Ma qualsiasi permutazione degli indici degli assi è possibile:
a.transpose(2,0,1)
# Out:
# array([[[ 0, 2],
# [ 4, 6],
# [ 8, 10]],
#
# [[ 1, 3],
# [ 5, 7],
# [ 9, 11]]])
a = np.arange(24).reshape((2,3,4)) # shape (2,3,4)
a.transpose(2,0,1).shape
# Out:
# (4, 2, 3)
Indicizzazione booleana
arr = np.arange(7)
print(arr)
# Out: array([0, 1, 2, 3, 4, 5, 6])
Il confronto con uno scalare restituisce un array booleano:
arr > 4
# Out: array([False, False, False, False, False, True, True], dtype=bool)
Questo array può essere utilizzato nell'indicizzazione per selezionare solo i numeri maggiori di 4:
arr[arr>4]
# Out: array([5, 6])
L'indicizzazione booleana può essere utilizzata tra diversi array (ad es. Array paralleli correlati):
# Two related arrays of same length, i.e. parallel arrays
idxs = np.arange(10)
sqrs = idxs**2
# Retrieve elements from one array using a condition on the other
my_sqrs = sqrs[idxs % 2 == 0]
print(my_sqrs)
# Out: array([0, 4, 16, 36, 64])
Rimodellare una matrice
Il numpy.reshape
(come numpy.ndarray.reshape
) restituisce una matrice della stessa dimensione totale, ma in una nuova forma:
print(np.arange(10).reshape((2, 5)))
# [[0 1 2 3 4]
# [5 6 7 8 9]]
Restituisce un nuovo array e non funziona sul posto:
a = np.arange(12)
a.reshape((3, 4))
print(a)
# [ 0 1 2 3 4 5 6 7 8 9 10 11]
Tuttavia, è possibile sovrascrivere l'attributo shape
di un ndarray
:
a = np.arange(12)
a.shape = (3, 4)
print(a)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
ndarray
questo comportamento potrebbe essere sorprendente, ma i file di ndarray
sono memorizzati in blocchi contigui di memoria e la loro shape
specifica solo in che modo questo flusso di dati deve essere interpretato come un oggetto multidimensionale.
Fino a un asse nella tupla di shape
può avere un valore di -1
. numpy
quindi la lunghezza di questo asse per te:
a = np.arange(12)
print(a.reshape((3, -1)))
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
O:
a = np.arange(12)
print(a.reshape((3, 2, -1)))
# [[[ 0 1]
# [ 2 3]]
# [[ 4 5]
# [ 6 7]]
# [[ 8 9]
# [10 11]]]
Molteplici dimensioni non specificate, ad es. a.reshape((3, -1, -1))
non sono consentite e a.reshape((3, -1, -1))
ValueError
.
Trasmissione di operazioni su array
Le operazioni aritmetiche sono eseguite elementwise su array Numpy. Per matrici di forma identica, ciò significa che l'operazione viene eseguita tra gli elementi negli indici corrispondenti.
# Create two arrays of the same size
a = np.arange(6).reshape(2, 3)
b = np.ones(6).reshape(2, 3)
a
# array([0, 1, 2],
# [3, 4, 5])
b
# array([1, 1, 1],
# [1, 1, 1])
# a + b: a and b are added elementwise
a + b
# array([1, 2, 3],
# [4, 5, 6])
Le operazioni aritmetiche possono anche essere eseguite su array di forme diverse tramite la trasmissione Numpy. In generale, un array viene "trasmesso" sull'altro in modo che le operazioni elementwise vengano eseguite su sottoselezioni di forma congruente.
# Create arrays of shapes (1, 5) and (13, 1) respectively
a = np.arange(5).reshape(1, 5)
a
# array([[0, 1, 2, 3, 4]])
b = np.arange(4).reshape(4, 1)
b
# array([0],
# [1],
# [2],
# [3])
# When multiplying a * b, slices with the same dimensions are multiplied
# elementwise. In the case of a * b, the one and only row of a is multiplied
# with each scalar down the one and only column of b.
a*b
# array([[ 0, 0, 0, 0, 0],
# [ 0, 1, 2, 3, 4],
# [ 0, 2, 4, 6, 8],
# [ 0, 3, 6, 9, 12]])
Per illustrare ulteriormente questo, considerare la moltiplicazione di array 2D e 3D con sotto-dimensioni congruenti.
# Create arrays of shapes (2, 2, 3) and (2, 3) respectively
a = np.arange(12).reshape(2, 2, 3)
a
# array([[[ 0 1 2]
# [ 3 4 5]]
#
# [[ 6 7 8]
# [ 9 10 11]]])
b = np.arange(6).reshape(2, 3)
# array([[0, 1, 2],
# [3, 4, 5]])
# Executing a*b broadcasts b to each (2, 3) slice of a,
# multiplying elementwise.
a*b
# array([[[ 0, 1, 4],
# [ 9, 16, 25]],
#
# [[ 0, 7, 16],
# [27, 40, 55]]])
# Executing b*a gives the same result, i.e. the smaller
# array is broadcast over the other.
Quando viene applicata la trasmissione di array?
La trasmissione ha luogo quando due array hanno forme compatibili .
Le forme vengono confrontate in base al componente a partire da quelle finali. Due dimensioni sono compatibili se sono uguali o uno di loro è 1
. Se una forma ha una dimensione superiore rispetto all'altra, i componenti eccedenti non vengono confrontati.
Alcuni esempi di forme compatibili:
(7, 5, 3) # compatible because dimensions are the same
(7, 5, 3)
(7, 5, 3) # compatible because second dimension is 1
(7, 1, 3)
(7, 5, 3, 5) # compatible because exceeding dimensions are not compared
(3, 5)
(3, 4, 5) # incompatible
(5, 5)
(3, 4, 5) # compatible
(1, 5)
Ecco la documentazione ufficiale sulla trasmissione di array .
Compila una matrice con il contenuto di un file CSV
filePath = "file.csv"
data = np.genfromtxt(filePath)
Sono supportate molte opzioni, consultare la documentazione ufficiale per l'elenco completo:
data = np.genfromtxt(filePath, dtype='float', delimiter=';', skip_header=1, usecols=(0,1,3) )
Array n-dimensionale di Numpy: il narray
La struttura dei dati di base in numpy è ndarray
(abbreviazione di matrice n- dimensionale). ndarray
s sono
- omogeneo (cioè contengono elementi dello stesso tipo di dati)
- contengono elementi di dimensioni fisse (dati da una forma , una tupla di n interi positivi che specificano le dimensioni di ciascuna dimensione)
Array monodimensionale:
x = np.arange(15)
# array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
x.shape
# (15,)
Array bidimensionale:
x = np.asarray([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14]])
x
# array([[ 0, 1, 2, 3, 4],
# [ 5, 6, 7, 8, 9],
# [10, 11, 12, 13, 14]])
x.shape
# (3, 5)
Tridimensionale:
np.arange(12).reshape([2,3,2])
Per inizializzare un array senza specificarne il contenuto, utilizzare:
x = np.empty([2, 2])
# array([[ 0., 0.],
# [ 0., 0.]])
Identificazione del tipo di dati e casting automatico
Il tipo di dati è impostato su float per impostazione predefinita
x = np.empty([2, 2])
# array([[ 0., 0.],
# [ 0., 0.]])
x.dtype
# dtype('float64')
Se vengono forniti alcuni dati, numpy indovina il tipo di dati:
x = np.asarray([[1, 2], [3, 4]])
x.dtype
# dtype('int32')
Si noti che quando si eseguono assegnazioni numpy tenterà di eseguire automaticamente il cast dei valori per adattarsi al tipo di dati di ndarray
x[1, 1] = 1.5 # assign a float value
x[1, 1]
# 1
# value has been casted to int
x[1, 1] = 'z' # value cannot be casted, resulting in a ValueError
Trasmissione di array
Vedi anche Trasmissione di operazioni su array .
x = np.asarray([[1, 2], [3, 4]])
# array([[1, 2],
[3, 4]])
y = np.asarray([[5, 6]])
# array([[5, 6]])
Nella terminologia matrix, avremmo un vettore 2x2 e un vettore 1x2. Ancora siamo in grado di fare una somma
# x + y
array([[ 6, 8],
[ 8, 10]])
Questo perché l'array y
è " allungato " a:
array([[5, 6],
[5, 6]])
per adattarsi alla forma di x
.
risorse:
- Introduzione al narray dalla documentazione ufficiale: l'array N-dimensionale (ndarray)
- Riferimento di classe: ndarray .