NumPy - people.unica.it - Università di...
Transcript of NumPy - people.unica.it - Università di...
NumPy: Informazioni di Base
Estensione che aggiunge supporto per vettori e matrici multidimensionali Fornisce:
funzioni matematiche di alto livello con cui operare (algebra lineare, trasformate di Fourier etc.).array multi-dimensionali (ndarray)
Scaricabile dal sito: http://numpy.scipy.org/
Importare il modulo
>>> from numpy import *>>> import numpy >>> import numpy as np
Array
Gli array in NumPy sono omogenei. A differenza delle liste di Python, tutti gli elementi sono dello stesso tipo (dtype).Gestiscono operazioni con dati di elevate dimensioni.Fornisce metodi di accesso, trasformazione, iterazione e inizializzazione di grande efficienza. Generalmente sono più efficienti delle liste convenzionali.Si può creare un array direttamente da una lista o da una tupla.
Array monodimensionali
Creazione di array>>> a = numpy.array([4,7,3]) #array da lista>>> a
array([4, 7, 3])
>>> a = numpy.array((4,7,3)) #array da tupla>>> a
array([4, 7, 3])
>>> a = numpy.array((4,7,3), float) #oppure>>> a = numpy.array((4,7,3), dtype = float)>>> a
array([4., 7., 3.])
>>> a = numpy.array(1,2,3,4) # errore: accetta solo una lista o una tupla!!
Array monodimensionali
Creazione di array>>> a = numpy.arange(10) #simile alla funzione range>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])>>> a = numpy.arange(1, 4)>>> a array([1, 2, 3])>>> a = numpy.arange(3, 24, 5)>>> a array([ 3, 8, 13, 18, 23])
>>> a.ndim # oppure >>> ndim(a) # numero di “assi” (dimensioni)
1>>> a.shape # oppure >>> shape(a)# numero di elementi per dimensione
(10,)>>> a.size # oppure >>> size(a) # numero di elementi totali
10>>> a.dtype.name # nome del tipo di dato nell’array
'int32'>>> type(a) # tipo della variable a
<type 'numpy.ndarray'>>>> b = a.copy() # oppure >>> b = copy(a) #crea una copia>>> b
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Array: funzioni di base
>>> a = numpy.array([0,1,2,3], int)>>> a[0] #indexing
0>>> a[0] = 10>>> a
array([10, 1, 2, 3])>>> a[0] = 10.6 #attenzione alla (non) conversione!!>>> a
array([10, 1, 2, 3])>>> a.fill(3) #imposta tutti gli elementi con lo stesso valore>>> a
array([3, 3, 3, 3])>>> a[:] = 3 # stesso comportamento di fill, ma più lento>>> a
array([3, 3, 3, 3])
Array: funzioni di base
>>> a= numpy.zeros(5) #array di zeri. Argomento: dimensione dell'array
>>> a
array([ 0., 0., 0., 0., 0.])
>>> a = numpy.zeros(5, int)
>>> a
array([0, 0, 0, 0, 0])
>>> a = numpy.ones(5) #array di 1. Argomento: dimensione dell'array
>>> a
array([ 1., 1., 1., 1., 1.])
>>> a = numpy.ones(5, int)
>>> a
array([1, 1, 1, 1, 1])
Array: funzioni di base
Array multidimensionali
>>> a = numpy.array([[0, 1, 2, 3], [4, 5, 6, 7]])
>>> a array([[0, 1, 2, 3],
[4, 5, 6, 7]])>>> a.shape (2, 4)
>>> a.ndim 2>>> a[1,3] 7>>> a[1,3] = -1
>>> a array([[ 0, 1, 2, 3], [ 4, 5, 6, -1]])>>> a[1] array([ 4, 5, 6, -1])
>>> numpy.zeros((3,3)) array([[ 0., 0., 0.],
[ 0., 0., 0.], [ 0., 0., 0.]])
>>> numpy.ones((3,3)) array([[ 1., 1., 1.],
[ 1., 1., 1.], [ 1., 1., 1.]])
#like
>>> array1 = numpy.array([[1, 2], [3, 4]])
>>> array1 array([[1 2] [3 4]])
>>> array2 = numpy.zeros_like(array1)
>>> array2 array([[0 0] [0 0]])
Array multidimensionali
Forma e dimensioni di array
#reshaping
>>> a = np.array(range(10), float)
>>> a array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
>>> a = a.reshape((5, 2))
>>> a array([[ 0., 1.], [ 2., 3.], [ 4., 5.], [ 6., 7.], [ 8., 9.]]) >>> a.shape (5, 2)
Forma e dimensioni di array
#trasposta
>>> a
array([[ 0., 1., 2.],
[ 3., 4., 5.]])
>>> a.transpose()
array([[ 0., 3.], [ 1., 4.], [ 2., 5.]])#vettore
>>> a
array([[ 1., 2., 3.], [ 4., 5., 6.]]) >>> a.flatten()
array([ 1., 2., 3., 4., 5., 6.])
Forma e dimensioni di array
#concatenazione
>>> a = numpy.array([1,2])
>>> b = numpy.array([3,4,5,6])
>>> c = numpy.array([7,8,9])
>>> numpy.concatenate((a, b, c))
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a = numpy.array([[1, 2], [3, 4]])
>>> b = numpy.array([[5, 6], [7,8]])
>>> numpy.concatenate((a,b))
array([[ 1, 2],
[ 3, 4], [ 5, 6], [ 7, 8]])
>>> numpy.concatenate((a,b), axis=0)
array([[ 1, 2], [ 3, 4], [ 5, 6], [ 7, 8]]) >>> numpy.concatenate((a,b), axis=1)
array([[ 1, 2, 5, 6], [ 3, 4, 7, 8]])
Slicing
50 51 52 53 54 55
40 41 42 43 44 45
30 31 32 33 34 35
20 21 22 23 24 25
10 11 12 13 14 15
0 1 2 3 4 5
Slicing
>>> a[0,3:5]array([3, 4])
50 51 52 53 54 55
40 41 42 43 44 45
30 31 32 33 34 35
20 21 22 23 24 25
10 11 12 13 14 15
0 1 2 3 4 5
Slicing
>>> a[0,3:5]array([3, 4])
>>> a[4:,4:]array([[44, 45],[54, 55]])
50 51 52 53 54 55
40 41 42 43 44 45
30 31 32 33 34 35
20 21 22 23 24 25
10 11 12 13 14 15
0 1 2 3 4 5
Slicing
>>> a[0,3:5]array([3, 4])
>>> a[4:,4:]array([[44, 45],[54, 55]])
>>> a[:,2]array([2,12,22,32,42,52])
50 51 52 53 54 55
40 41 42 43 44 45
30 31 32 33 34 35
20 21 22 23 24 25
10 11 12 13 14 15
0 1 2 3 4 5
Slicing
>>> a[0,3:5]array([3, 4])
>>> a[4:,4:]array([[44, 45],[54, 55]])
>>> a[:,2]array([2,12,22,32,42,52])
>>> a[2::2,::2]array([[20, 22, 24],[40, 42,
44]])
50 51 52 53 54 55
40 41 42 43 44 45
30 31 32 33 34 35
20 21 22 23 24 25
10 11 12 13 14 15
0 1 2 3 4 5
Slicing
Lo slicing crea delle referenze all'array originale>>> a = array((0,1,2,3,4))
>>> b = a[2:4]
>>> b
array([2,3])
>>> b[0] = 10
>>> b
array([10,3])
# cambio b → cambia a!
>>> a
array([ 1, 2, 10, 3, 4])
Fancy indexing
>>> a = arange(0,80,10)
# fancy indexing per posizione
>>> y = a[[1, 2, -3]]
>>> y
[10 20 50]
# fancy indexing booleano
>>> mask = numpy.array([0,1,1,0,0,1,0,0], dtype=bool)
>>> y = a[mask]
>>> y
[10,20,50]
0 10 20 30 40 50 60 70
10 20 50
a
y
Fancy indexing multidimensionale
50 51 52 53 54 55
40 41 42 43 44 45
30 31 32 33 34 35
20 21 22 23 24 25
10 11 12 13 14 15
0 1 2 3 4 5
Fancy indexing multidimensionale
>>> a[(0,1,2,3,4),(1,2,3,4,5)] array([ 1, 12, 23, 34, 45])
50 51 52 53 54 55
40 41 42 43 44 45
30 31 32 33 34 35
20 21 22 23 24 25
10 11 12 13 14 15
0 1 2 3 4 5
Fancy indexing multidimensionale
>>> a[(0,1,2,3,4),(1,2,3,4,5)] array([ 1, 12, 23, 34, 45])
>>> a[3:,[0, 2, 5]] array([[30, 32, 35], [40, 42, 45]]) [50, 52, 55]])
50 51 52 53 54 55
40 41 42 43 44 45
30 31 32 33 34 35
20 21 22 23 24 25
10 11 12 13 14 15
0 1 2 3 4 5
Fancy indexing multidimensionale
>>> a[(0,1,2,3,4),(1,2,3,4,5)] array([ 1, 12, 23, 34, 45])
>>> a[3:,[0, 2, 5]] array([[30, 32, 35], [40, 42, 45]]) [50, 52, 55]])
>>> mask = array([1,0,1,0,0,1], dtype=bool) >>> a[mask,2] array([2,22,52])
50 51 52 53 54 55
40 41 42 43 44 45
30 31 32 33 34 35
20 21 22 23 24 25
10 11 12 13 14 15
0 1 2 3 4 5
Fancy indexing multidimensionale
>>> a[(0,1,2,3,4),(1,2,3,4,5)] array([ 1, 12, 23, 34, 45])
>>> a[3:,[0, 2, 5]] array([[30, 32, 35], [40, 42, 45]]) [50, 52, 55]])
>>> mask = array([1,0,1,0,0,1], dtype=bool) >>> a[mask,2] array([2,22,52])
50 51 52 53 54 55
40 41 42 43 44 45
30 31 32 33 34 35
20 21 22 23 24 25
10 11 12 13 14 15
0 1 2 3 4 5
A differenza dello slicing, il fancy indexing non crea referenze all'array originale, ma crea delle copie
>>> a = array([[1,2,3], [4,5,6]])
# somma di tutti gli elementi.
>>> a.sum()
21
# somma lungo gli assi.
>>> a.sum(axis=0) #primo asse
array([5, 7, 9])
>>> a.sum(axis=-1) #ultimo asse
array([6, 15])
# prodotto di tutti gli elementi.
>>> a.prod()
720
# prodotto lungo il primo asse.
>>> a.prod(axis=0)
array([4, 10, 18])
Array: operazioni di base
>>> a = array([2.,3.,0.,1.])
>>> a.min(axis=) 0.>>> a = array([2.,1.,0.,3.])
>>> a.max(axis=0) 3.#restituisce l'indice dell'elemento di minimo valore.
>>> a.argmin(axis=0) 2#restituisce l'indice dell'elemento di massimo valore.
>>> a.argmax(axis=0) 1>>> a = numpy.array([[1,2,3], [4,5,6]], float)
>>> a.clip(3,5)#valori minori 3 → 3; valori maggiori di 5 → 5.
>>> a
array([[ 3., 3., 3.], [ 4., 5., 5.]])
Array: operazioni di base
Le seguenti funzioni restituiscono il valore intero più vicino, rispettivamente, per difetto, per eccesso e arrotondato
>>> a = np.array([1.1, 1.5, 1.9], float) >>> numpy.floor(a)
array([ 1., 1., 1.])
>>> numpy.ceil(a)
array([ 2., 2., 2.])
>>> numpy.rint(a)
array([ 1., 2., 2.])
Array: operazioni di base
>>> a = numpy.array([[1,2,3], [4,5,6]], float)
#valore medio
>>> a.mean()
3.5
>>> a.mean(axis=0)
array([2.5, 3.5, 4.5])
>>> average(a, axis=0)
array([2.5, 3.5, 4.5])
#deviazione standard
>>> a.std()
1.707825127659933
>>> a.std(axis=0)
array([ 1.5, 1.5, 1.5])
#varianza
>>> a.var()
2.9166666666666665
>>> a.var(axis=0)
array([2.25, 2.25, 2.25])
Array: funzioni statistiche
Gli operatori aritmetici vengono applicati elemento per elemento. Operazioni più efficienti rispetto ad una iterazione elemento per elemento
>>> a = numpy.array([20,30,40,50])>>> b = numpy.arange(4)>>> b array([0, 1, 2, 3])>>> a-b array([20, 29, 38, 47])>>> b*b array([0, 1, 4, 9])>>> b**2 array([0, 1, 4, 9])
Operazioni matematiche
Operazioni matematiche
Corrispondenza tra operatori e funzioni
a + b → numpy.add(a,b)
a - b → numpy.subtract(a,b)
a * b → numpy.multiply(a,b)
a % b → numpy.remainder(a,b)
a / b → numpy.divide(a,b)
a ** b → numpy.power(a,b)
== → numpy.equal(a,b)
!= → numpy.not_equal(a,b)
> → numpy.greater(a,b)
>= → numpy.greater_equal(a,b)
< → numpy.less(a,b)
<= → numpy.less_equal(a,b)
Funzioni
Trigonometrichesin(a)
cos(a)
tan(a)
arcsin(a)
arccos(a)
arctan(a)
sinh(a)
cosh(a)
tanh(a)
arcsinh(a)
arccosh(a)
arctanh(a)
Altre funzioniexp(x)log(x)
log10(x)sqrt(x)
absolute(x)cconjugate(x)
negative(x)ffabs(x) hypot(x,y)fmod(x,y) maximum(x,y)minimum(x,y)
Calcolo matriciale
Prodotto scalare>>> a = numpy.array([1, 2, 3],float) >>> b = numpy.array([0, 1, 1],float) >>> numpy.dot(a, b) 5.0
Le maggiori funzioni per il calcolo matriciale sono comprese nel sotto-modulo linalg
#calcolo del determinante
>>> a = numpy.array([[4, 2, 0], [9, 3, 7], [1, 2, 1]], float)
>>> a
array([[4., 2., 0.],
[9., 3., 7.],
[1., 2., 1.]])
>>> numpy.linalg.det(a)
-53.999999999999993
Calcolo matriciale
#autovalori ed autovettori
>>> vals, vecs = numpy.linalg.eig(a)
>>> vals array([ 9. , 2.44948974, -2.44948974]) >>> vecs array([[-0.3538921 , -0.56786837, 0.27843404], [-0.88473024, 0.44024287, -0.89787873], [-0.30333608, 0.69549388, 0.34101066]]) #matrice inversa
>>> b = numpy.linalg.inv(a)
>>> b array([[0.14814815, 0.07407407, -0.25925926], [0.2037037 , -0.14814815, 0.51851852], [-0.27777778, 0.11111111, 0.11111111]])
Broadcasting
Operazioni tra più elementi di diverse dimensioni. Se possibile tutti gli array vengono convertiti in elementi aventi la stessa dimensioneEsempio:
>>> x = numpy.array([1,2,3,4]) >>> y = numpy.array([[10],[20],[30]]) >>> numpy.add(x,y) [[11 12 13 14] [21 22 23 24] [31 32 33 34]]
Broadcasting
0 1 2
0 1 2
0 1 2+
0 1 2
30
20
10
0
30
20
10
0
+
30
20
10
0 0 1 2
= =
30
20
10
0
+
0 1 2
0 1 2
0 1 2
0 1 2
30 30 30
20 20 20
10 10 10
0 0 0
+
0 1 2
0 1 2
0 1 2
0 1 2
30 30 30
20 20 20
10 10 10
0 0 0
= =
Broadcasting
0 1 2
0 1 2
0 1 2+
0 1 2
30
20
10
0
30
20
10
0
+
30
20
10
0 0 1 2
= =
30
20
10
0
+
0 1 2
0 1 2
0 1 2
0 1 2
30 30 30
20 20 20
10 10 10
0 0 0
+
0 1 2
0 1 2
0 1 2
0 1 2
30 30 30
20 20 20
10 10 10
0 0 0
= =
30 31 32
20 21 22
10 11 12
0 1 2
=
Broadcasting
Il broadcasting è possibile se il numero di colonne della prima è uguale al numero di righe della seconda, altrimenti l'interprete Python restituisce l'eccezione “ValueError: frames are not aligned”
+
30 30 30
20 20 20
10 10 10
0 0 0 0 1 2
=3
4x3 4
mismatch!