Come operare su interi array con un singolo comando\n",
"
Funzioni che agiscono su tutto un array\n",
"
Come selezionare gli elementi di un array che soddisfano una condizione\n",
"
Array a due dimensioni: le matrici\n",
"
L'algebra lineare\n",
"
Array multidimensionali\n",
"
Come vettorializzare una funzione scalare\n",
"
Leggere e scrivere array su un file di testo\n",
"
\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"## 7.1 Introduzione\n",
"\n",
"Il linguaggio Python di base (incluse le librerie standard) fornisce strumenti sufficienti per completare semplici progetti computazionali. Tuttavia, esistono librerie Python dedicate che forniscono funzionalità estese che\n",
"\n",
"- forniscono strumenti numerici per automatizzare operazioni ricorrenti\n",
"\n",
"- sono semplici da usare\n",
"\n",
"- sono più efficienti in termini di tempo di CPU e di esigenze di memoria degli strumenti in Python base.\n",
"\n",
"Citiamo tre librerie in particolare:\n",
"\n",
"- Il modulo `numpy`, introdotto in 07_numpy, che fornisce strumenti numerici. Numpy contiene fra le altre cose molte funzioni per manipolazioni statistiche che vengono presentate in 09_numpy_statistics.\n",
"\n",
"- Il modulo `matplotlib`, introdotto in 08_plots, che permette di creare grafici.\n",
"\n",
"- Il modulo `scipy` (SCIentific PYthon), introdotto in 10_scipy, che fornisce un gran numero di algoritmi numerici.\n",
"\n",
"Molti degli algoritmi numerici resi disponibili da `numpy` e `scipy` sono forniti da librerie compilate, di solida tradizione, che spesso sono scritte in Fortran o C. Vengono quindi eseguite molto più velocemente di codice scritto in puro Python (che è interpretato). Generalmente, un codice compilato è due ordini di grandezza più veloce di un codice in puro Python.\n",
"\n",
"Come al solito, si può utilizzare la funzione `help` su ciascuno dei metodi numerici per accedere alla documentazione."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 7.2 Numpy e gli array\n",
"\n",
"La librery NumPy (NUMerical PYthon) fornisce un nuovo tipo di struttura dei dati chiamata `array`s che permette di eseguire in modo efficiente operazioni su vettori e matrici. Fornisce inoltre diverse operazioni legate all'algebra lineare (come risolvere sistemi di equazioni lineari, calcolo di autovettori e autovalori). Viene tradizionalmente importata come `np`. \n",
"\n",
"NumPy introduce un nuovo tipo di dati detto “`array`”. Un array *sembra* molto simile a una lista ma può contenere solo elementi di un singolo tipo (mentre una lista può contenere oggetti di tipo diverso). Questo significa che gli array possono essere scritti in memoria in modo più efficiente. Gli array sono la struttura di dati migliore per i calcoli numerici in cui spesso si ha a che fare con vettori e matrici di tipo omogeneo.\n",
"\n",
"Vettori, matrici bidimensionali e matrici con più di due indici sono tutti chiamati “arrays” in NumPy.\n",
"\n",
"### 7.2.1 Vettor1 (1d-arrays)\n",
"\n",
"La struttura dati data che useremo più spesso è il vettore. Qualche esempio di come crearne uno:\n",
"\n",
"- Conversione di una lista (o tuple) in un array usando `numpy.array`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"x = np.array([0, 0.5, 1, 1.5])\n",
"print(x)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"type(x)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"type([0, 0.5, 1, 1.5])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- numpy maneggia nativamente numeri complessi. Non esiste cnumpy."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.array([1+1j,2-1j])\n",
"b = np.array([1-1j,2-1j])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a*b"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a+b"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Attenzione!
\n",
" Notate come la rappresentazione sullo schermo di un array sia diversa se si invoca semplicemente il corrispondente simbolo oppure se si chiama la funzione print. La differenza è legata a due diverse funzioni intrinseche __str__ e __repr__ che possono essere utilizzate nella definizioni di Classi, di cui non parleremo nel corso.\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Creazione di un vettore usando \"arange\":"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = np.arange(0, 2, 0.5)\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Creazione di un vettore di zeri, di uno"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = np.zeros(4)\n",
"print(x)\n",
"y = np.ones(10)\n",
"print(y)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Aggiungere, inserire, eliminare elementi di un array\n",
"\n",
"`Numpy` ha i metodi `np.append`, `np.insert`, `np.delete` che permettono di modificare il numero di elementi di un `array`. Tutti questi metodi per&ograsve;non agiscono `in-place` ma creano e ritornano un nuovo `array`, quindi sono computazionalmente costosi. Per questa ragione è preferibile creare un `array` con metodo come `zeroes` e `ones` e poi modificare i valori. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### I comandi linspace() e logspace()\n",
"\n",
"In Numpy esiste il comando `linspace(x0, x1, n)`, che genera una lista di `n` elementi equidistanti fra `x0` e `x1` (inclusi). Il comando `logspace(x0, x1, n)` genera una lista di `n` elementi equidistanti, in scala logaritmica, fra `10\\*\\*x0` e `10\\*\\*x1`; è utile per fare plot logaritmici come vedremo in 08_plots. Alcuni esempi:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.linspace(0,10,1001)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.linspace(-1,1,21)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ricordate che i primi due argomenti di logspace sono i logaritmi in base 10 del punto iniziale e di quello finale. Il terzo parametro è il numero di divisioni, estremi inclusi."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.logspace(1,4,4)\n",
"#np.logspace(1.7,4.4,40)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Come scegliere o modificare il `tipo` di dati di un array"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Quando viene creato un array è possibile specificare il tipo di dati che contiene. I tipi possibili sono: 'float', 'complex', 'int', 'bool', 'str' and 'object'. Un controllo più fine si può avere usando espressioni come 'float32', 'float64', 'int8', 'int16' oppure 'int32'; l'intero specifica il numero di bytes. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"array_f = np.array([1,2,3.14], dtype=float)\n",
"array_i = np.array([1.,2.2,3], dtype='int16')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"array_f"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"array_i"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.array([1,2,123456790],dtype='int32')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.arange(1.3,2.2,0.1,dtype=complex)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Il tipo di un array può essere modificato con il metodo astype"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"array_f.astype(complex)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"array_f.astype('int16')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 7.2.2 Operazioni su array\n",
"\n",
"- Una volta che l'array esiste, possiamo definire e recuperare il valore degli elementi. Per esempio:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = np.zeros(4)\n",
"x[0] = 3.4\n",
"x[2] = 4\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- I metodi di slicing per le stringhe/liste/ntuple si possono applicare anche agli array:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(x[0])\n",
"print(x[0:-1])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- La lunghezza di un array si ottiene con `len`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"len(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Quando abbiamo un array possiamo eseguire operazioni su ogni elemento con un solo comando. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = np.arange(0, 2, 0.5)\n",
"print(x)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(x + 10)\n",
"print(x*33)\n",
"print(x ** 2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La maggior parte delle operazioni (`+`, `-`, `*`, `/`) agiscono su tutto un array in un solo colpo, elemento per elemento."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"y1 = np.array([1.,2.,3.])\n",
"y2 = np.array([-1.,-10,+100])\n",
"y1+y2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Nel modulo numpy sono definite tutte le funzioni matematiche più comuni in modo che agiscano su tutti gli elementi di un array. Sono definite anche le costanti come np.e e np.pi. In generale è superfluo importare separatamente il modulo math."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(np.sin(x))\n",
"print(np.e)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La funzione `mod` corrisponde alla operazione modulo `%` con molte opzioni in più (Hint: help(np.mod))."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = np.arange(10)\n",
"print(x)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.mod(x,6)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Il modo migliore di utilizzare una funzione in numpy è definire l'array dei punti in cui la funzione deve essere calcolata e poi applicare la funzione all'array. \n",
"Esempio: per calcolare i valori del polinomio y = 3\\* x\\*\\*3 - 2\\*x\\*\\*2 + 1 fra -5 e 5:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def myfunc(arr):\n",
" return 3*arr**3 -2*arr*arr +1\n",
"\n",
"x = np.linspace(-5,5,101)\n",
"print(x)\n",
"res = myfunc(x)\n",
"res"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"check:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"3*(-4.9)**3 -2*(-4.9)**2 +1."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Attenzione!
\n",
" È sbagliato e dannoso iterare esplicitamente, per esempio usando un `for` loop, sulle componenti di un array.\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Come estrarre più elementi da un array"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = np.arange(5,15)\n",
"x"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x1 = [x[2],x[3],x[5]]\n",
"print(x1)\n",
"type(x1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Per ottenere un array dal risultato precedente:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x1 = np.array(x1)\n",
"print(x1)\n",
"type(x1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Come estrarre più elementi da un array usando un array di indici"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ind = [2,3,5]\n",
"x[ind] # Restituisce un array"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Imparare Facendo
\n",
" \n",
"\n",
"
Create un array A di 10 elementi uguali a -2.\n",
"
Create un array B di 21 elementi equidistanziati fra -np.pi e np.pi.\n",
"
Create un array C aggiungendo np.pi a tutii gli elementi di B.\n",
"
Invertite l'ordine degli elementi di C.\n",
"
Create un array D di elementi distanziati di 0.15 fra -2 e 1 in modo che 1 sia incluso.\n",
"
Estraete il terzultimo elemento di D.\n",
"
Create l'array E del quadrato degli elementi di D.\n",
"
Calcolate la differenza, elemento per elemento, fra E e D.\n",
"
Calcolate il valore di sin(2*x) in 201 punti x equidistanziati fra 0 e np.pi \n",
"
Costruite una funzione parabola(a,b,c,xmin,xmax,npoints) che restutuisca un array di npoints valori di y\n",
" in npoints punti x equidistanziati fra\n",
" xmin e xmax (compresi) appartenenti alla parabola y = a*x**2 + b*x + c.\n",
"
\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Come estrarre da un array gli elementi che soddisfano una condizione data. Nell'esempio gli elementi dispari. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"arr = np.array([2, 3, 4, 5, 6, 7, 8, 9])\n",
"\n",
"arr[arr % 2 == 1]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"oppure, con più flessibilità sul modo di imporre le condizioni:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.array([x for x in arr if x% 2 == 1])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Come sostituire in un array gli elementi che soddisfano una condizione data con un valore fisso."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n",
"\n",
"arr[arr % 2 == 1] = -1\n",
"arr"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Come ottenere lo stesso risultato senza modificare l'array iniziale. `np.where(condition,X,Y)` restituisce l'elemento di `X` se la condizione è vera e l'elemento di `Y` se la condizione è falsa."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#help(np.where)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"arr = np.arange(2,10)\n",
"out = np.where(arr % 2 == 1, -1, arr)\n",
"print(arr)\n",
"out"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`np.where(condition)` restituisce una ntupla il cui primo elemento è l'array degli *indici* degli elementi per cui la condizione è vera."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"out = np.where(arr % 2 == 1)\n",
"out"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Per estrarre i corrispondenti elementi:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"arr[out]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Per imporre più condizioni si può utilizzare la notazione:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n",
"np.where( (arr>=1) & (arr<+7) )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le parentesi tonde attorno alle condizioni sono indispensabili perchè l'operatore `&` ha precedenza più alta degli operatori di confronto. Le parentesi forzano Python a valutare le disuguaglianze prima di combinarle con `and`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Si possono anche combinare le varie condizioni in una condizione unica con `logical_and`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"index = np.where(np.logical_and(a>=5, a<=10))\n",
"a[index]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Come estrarre gli elementi \"unici\" e il numero di volte in cui compaiono in un array:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"uniqs, counts = np.unique(out, return_counts=True)\n",
"print(\"Unique items : \", uniqs)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"uniqs2 = np.unique(out)\n",
"uniqs2"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#help(np.unique)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Come selezionare gli elementi comuni fra due array."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.array([1,2,3,2,3,4,3,4,5,6])\n",
"b = np.array([7,2,10,2,7,4,9,4,9,8])\n",
"\n",
"np.intersect1d(a,b)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Come eliminare da un array `a` tutti gli elementi che compaiono anche in `b`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.array([1,2,3,4,5])\n",
"b = np.array([5,6,7,8,9])\n",
"\n",
"np.setdiff1d(a,b)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.array([1,2,3,2,3,4,3,4,5,6])\n",
"b = np.array([7,2,10,2,7,4,9,4,9,8])\n",
"\n",
"np.where(a == b)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.asarray(a == b)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.asarray(a == b).nonzero() # restituisce gli indici degli elementi non nulli cioè di quelli non False"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Come ordinare un array.\n",
"\n",
"Python ha il metodo `sort` e la funzione `sorted` per ordinare liste. In numpy si può usare la funzione `numpy.sort` che restituisce una copia ordinata dell'array passato in input."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = np.array([1,3,2])\n",
"y = np.sort(x)\n",
"print(y)\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Per ordinare un array in ordine decrescente una possibilità è:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"y1 = np.sort(x)[::-1]\n",
"print(y1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 7.2.3 Convertire da array a lista o tuple\n",
"\n",
"Per convertire un array in una lista o una si possono usare le funzioni python standard `list(s0)` e `tuple(s0)` che accettano una sequenza `s0` come input e ritornano rispettivamente una lista e una ntupla:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.array([1, 4, 10])\n",
"a"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"list(a)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tuple(a)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Imparare Facendo
\n",
" \n",
"\n",
"
Dall'array A = np.arange(20, 101) estrarre l'array dei multipli di 13.\n",
"
Dall'array B = np.cos(np.linspace(0,np.pi,100)) estarre gli elementi di valore compreso fra -0.1 e 0.3.\n",
"
Dall'array C = np.arange(-4., 2.,0.3) estrarre gli elementi il cui quadrato sia compreso fra 1 e 4.\n",
"
Dall'array D = np.array(['a','b','a','e','e','a']) estrarre gli elementi unici e le corrispondenti molteplicità.\n",
"
Estrate gli elementi comuni fra gli array E = np.arange(2.,10.,0.2) e F = np.arange(-1.,7.,0.4).\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 7.2.4 %timeit per valutare il tempo di esecuzione di un comando\n",
"È spesso utile misurare il tempo necessario per eseguire dei comandi. Jupyter fornisce la funzione %timeit che possiamo utilizzare per mostrare la maggiore velocità delle operazioni di Numpy su array rispetto alle operazioni di math su liste."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def forloopmethod(N):\n",
" a1 = [0]*N\n",
" for i in range(N):\n",
" a1[i] = float(i)**2 # passare a numeri reali rende l'operazione più veloce \n",
" return sum(a1)\n",
"\n",
"def numpymethod(N):\n",
" a3 = np.sum(np.arange(0, N)**2, dtype='d') # dtype = 'd' vuol dire double precision\n",
" return a3\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"N = 1000000\n",
"\n",
"%timeit forloopmethod(N)\n",
"%timeit numpymethod(N)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 7.2.5 Matrici (2d-arrays)\n",
"\n",
"Ecco due modi per creare un array a due dimensioni:\n",
"\n",
"- Convertendo una lista di liste (o tuples) in un array (Ciascuna sottolista corrisponde a una riga della matrice):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = np.array([\n",
" [1, 2, 3], [4, 5, 6]\n",
"])\n",
"x"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Usare il metodo `zeros` (`ones`) per creare una matrice di zeri (uno). Un esempio con 5 righe e 4 colonne:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = np.zeros((5, 4))\n",
"x"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La \"forma\" di una matrice può essere trovata con il comando `shape` (in questo caso ci sono 2 righe e 3 colonne):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x=np.array([[1, 2, 3], [4, 5, 6]])\n",
"print(x)\n",
"x.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La \"forma\" di una matrice può essere modificata con il comando/metodo `reshape`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.arange(6).reshape((3, 2)) # metodo"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.reshape(a, (2, 3)) # funzione"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"I singoli elementi possono essere recuperati con la sintassi seguente:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x=np.array([[1, 2, 3], [4, 5, 6],[7,8,9]])\n",
"x[0, 0] "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x[0, 1]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x[0, 2]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x[1, 0]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Per recuperare una riga o una colonna:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x[:, 0]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x[0,:]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Per recuperare una lista di righe o colonne:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x[[0,1],:]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x[np.arange(1,3),:]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La stessa sintassi si utilizza per modificare un elemento della matrice:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x[1,0] = 157\n",
"x"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Un esempio su come sostituire elementi multipli in una matrice \n",
"Supponiamo di voler creare la matrice:\n",
" $$A = \\begin{bmatrix} -2 & 0 & 0 \\\\ 0 & 5 & 0 \\\\ 0 & 0 & 1 \\end{bmatrix}$$\n",
" Un metodo è il seguente: "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"A = np.zeros((3,3))\n",
"print(A)\n",
"vec = np.array([-2,5,1])\n",
"indices = np.array([0,1,2])\n",
"A[indices,indices] = vec\n",
"A"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Un esempio che utilizza due array diversi per gli indici sulle righe e gli indici sulle colonne:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"A = np.zeros((4,4))\n",
"ind_row = np.array([0,2])\n",
"ind_col = np.array([1,3])\n",
"vec1 = np.array([5,1])\n",
"A[ind_row,ind_col] = vec1\n",
"A"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Imparare Facendo
\n",
" \n",
"\n",
"
Costruite la matrice\n",
" $$\n",
"A = \\left( \\begin{matrix}\n",
"1 & 2 \\\\\n",
"3 & 4 \\\\ \n",
"\\end{matrix} \\right).\n",
"$$\n",
"Estrate da $A$, in forma di array, la prima colonna, la seconda, la prima riga, la seconda.\n",
"
Create una matrice A con 4 righe e due colonne i cui elementi siano uguali a -2.\n",
"
In A sostituite tutti gli elementi della seconda riga con 33.\n",
"
Create un array B di numeri interi fra 1 e 18. Trasformate B in un array di shape (9,2), (2,9), (6,3). \n",
" Perchè non è possibile trasformare A in un array di shape (5,4)?\n",
"
\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 7.2.6 Operazioni standard in Algebra Lineare\n",
"\n",
"#### Vettori\n",
"\n",
"Prodotto interno (scalare), esterno, vettoriale (quest'ultimo solo in due o tre dimensioni)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = np.array([1, 4, 0], float)\n",
"y = np.array([2, 2, 1], float)\n",
"print(\"Matrices and vectors.\")\n",
"print(\"x:\")\n",
"print(x)\n",
"print(\"y:\")\n",
"print(y)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"Inner product of x and y:\")\n",
"print(np.inner(x, y))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"Outer product of x and y:\")\n",
"print(np.outer(x, y))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"Cross product of x and y:\")\n",
"print(np.cross(x, y))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Moltiplicazione fra matrici\n",
"\n",
"Due arrays possono essere moltiplicato nel senso usuale dell'algebra lineare usando `numpy.dot`. Ecco un esempio:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import numpy.random \n",
"A = numpy.random.rand(5, 5) # genera matrice random 5 by 5 \n",
"x = numpy.random.rand(5) # genera un vettore di 5 elementi\n",
"print(A)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(x)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"b=np.dot(A, x) # multiplica la matrice A per il vettore x \n",
"print(b)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Per moltiplicare due matrici ci sono anche il metodo `matmul` e l'operatore `@` che è la soluzione più semplice introdotta in Python 3.5"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"M1 = np.array([[0,1],[1,2]])\n",
"M2 = np.array([[1,0],[0,-1]])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.matmul(M1,M2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"M1@M2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Risolvere un sistema di equazioni lineari\n",
"\n",
"Per risolvere un sistema di equazioni lineari `A*x = b`, dato in forma matriciale (cioè `A` è una matrice e `x` e `b` sono vettori, con `A` e `b` noti), possiamo usare la libreria di algebra lineare `linalg` di `numpy`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy.linalg as LA\n",
"x = LA.solve(A, b)\n",
"x"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"check:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(np.dot(A,x))\n",
"print(b)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Determinante e traccia"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"X = np.array([[1, 2], [4, 5]])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"LA.det(X)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.trace(X)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#help(np.linalg)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Matrice inversa e trasposta"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"X = np.array([[1, 2], [4, 5]])\n",
"Xinv = LA.inv(X)\n",
"print(Xinv)\n",
"X@Xinv"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Xt = np.transpose(X)\n",
"print(Xt)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Calcolare autovettori e autovalori (eigenvector e eigenvalue)\n",
"\n",
"Ricordiamo che data una matrice $M$, il vettore non nullo $v_i$ è un autovettore di $M$ e lo scalare $\\lambda_i$\n",
"è il corrispondente autovalore se:\n",
"$$ M\\,v_i = \\lambda_i \\, v_i.$$\n",
"Ecco un piccolo esempio che calcola gli autovettori e autovalori di una matrice con il comando `eig`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy.linalg as LA\n",
"import numpy as np\n",
"\n",
"R = np.array([[1,2,3], [1,0,1], [0,1,2]])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"LA.det(R)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"evalues, evectors = LA.eig(R)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(evalues)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Controlliamo se il prodotto degli autovalori è uguale al determinante:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.prod(evalues)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(evectors)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Attenzione:** gli autovettori sono disposti sulle **colonne**. \n",
" Verifica:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"A1=evectors[:,0]\n",
"print(A1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(np.dot(R,A1))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(evalues[0]*A1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ciascuno di questi comandi fornisce la propria documentazione. Per esempio, `help(LA.eig)` fornisce dettagli sulla funzione che calcola autovettori e autovalori (Avendo importato `numpy.linalg` come `LA`)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Ordinare gli elementi di una matrice"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"X = np.array(\n",
"[[6, 3, 7],\n",
" [2, 6, 4],\n",
" [7, 2, 5]] \n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ordinare le colonne:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.sort(X, axis=0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ordinare le righe:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.sort(X, axis=1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Imparare Facendo
\n",
" \n",
"\n",
"
Calcolate la lunghezza del vettore A = np.array([0.3,-1.7,0.8]) usando il prodotto scalare.\n",
"
Determinate se la matrice B = np.array([[0,3,1],[-1,2,0],[1,1,3]]) è invertibile.\n",
"
Cercate nella documentazione di numpy come calcolare l'inverso di una matrice. Se possibile, calcolate la matrice inversa di B.\n",
"
Per ruotare un vettore colonna bidimensionale di un angolo theta è sufficiente moltiplicarlo per la matrice \n",
" R(theta) = [[cos(theta),-sin(theta)],[sin(theta),cos(theta)]].\n",
" Costruite una funzione rot(v,theta) che dato un vettore reale di lunghezza 2 restituisca il vettore ruotato di\n",
" theta. Testate la funzione con v = np.array([1,1]) e theta = pi/2.\n",
"
Costruite la Tavola Pitagorica utilizzando il prodotto esterno.\n",
"
\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 7.2.7 Come vettorializzare una funzione\n",
"\n",
"Per avere programmi veloci è necessario evitare di ciclare sugli elementi di vettori e matrici usando invece algoritmi vettorializzati. Il primo passo per convertire un algoritmo scalare in un algoritmo vettorializzato è costruire delle funzioni che accettino input vettoriali.\n",
" \n",
"AVVERTENZA: è quasi sempre possibile trovare funzioni di Numpy, quindi già vettorializzate, che facciano quello che ci serve. `vectorize` va utilizzata come ultima risorsa quando tutte le ricerche nella documentazione e in rete si sono rivelate vane. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def Theta(x):\n",
" \"\"\"\n",
" Implemenazione scalare della funzione a gradino di Heaviside.\n",
" \"\"\"\n",
" if x >= 0:\n",
" return 1\n",
" else:\n",
" return 0\n",
" \n",
"Theta(0.3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Se passiamo a `Theta` un array o qualunque altro oggetto iterabile otteniamo un errore:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Theta((1,2))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Theta(np.array([-3,-2,-1,0,1,2,3]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Per ottenere una versione vettorializzata di Theta si può utilizzare la funzione di Numpy `vectorize`. In molti casi `vectorize` riesce a creare una funzione vettoriale che opera come la funzione scalare ma su tutti gli elementi di qualunque array:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Theta_vec = np.vectorize(Theta) # Theta_vec è una funzione diversa da Theta"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Theta_vec(np.array([-3,-2,-1,0,1,2,3]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Copia shallow e copia deep di array numpy"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.array([1,2,3])\n",
"b = a\n",
"a[2] = 22"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(b)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La copia con [:] non è sufficiente a creare una deep copy"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.array([1,2,3])\n",
"b = a[:]\n",
"a[2] = 22"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(b)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Bisogna usare la funzione deepcopy nlla libreria `copy`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import copy\n",
"a = np.array([1,2,3])\n",
"b = copy.deepcopy(a)\n",
"a[2] = 22"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(b)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 7.2.8 Array multidimensionali\n",
"Tipicamente le funzioni di numpy possono operare su array multidimensionali. È quindi necessario poter controllare come la funzione agisce sull'array. Un caso tipico è far operare la funzione lungo un singolo asse (axis) dell'array. Un semplice esempio usando la funzione `sum`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.sum([[0, 1], [3, 5]])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.sum([[0, 1], [3, 5]], axis=0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.sum([[0, 1], [3, 5]], axis=1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 7.2.9 Come importare dentro degli array i dati contenuti in un file di testo\n",
"\n",
"Quando si debba trattare una grande massa di dati è essenziale poterli importare ed esportare su file in modo veloce.\n",
" \n",
"Numpy fornisce la funzione `loadtxt`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"dataPt, time, height, error = np.loadtxt( \"../Data/CadutaLiberaDati.txt\", skiprows=5 , unpack=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Il parametro `skiprows=5` dice a `loadtxt` di ignorare le prime cinque righe che costituiscono l'`header` del file. Il parametro `unpack=True` dice di estrarre i dati caricandoli nell'ntupla di array a primo membro. Il comando assume che i dati siano separati da uno o più spazi."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(height)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Se i dati sono contenuti in un Comma-Separated Values file (CSV), una alternativa molto comune, è sufficiente specificare il separatore con la keyword `delimiter`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"dataPt, time, height, error = np.loadtxt(\"../Data/CadutaLiberaDati.csv\", skiprows=5 , unpack=True, delimiter=',')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Si possono importare da un file con dati testuali e numerici usando `dtype=str`. In questo caso i dati sono rappresentati come stringhe."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"gender, weight, age = np.loadtxt(\"../Data/mixed_data.txt\", skiprows=2 , unpack=True, dtype=str)\n",
"print(gender)\n",
"print(weight)\n",
"print(age)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"È poi possibile convertire parte degli array in un formato numerico usando il metodo `astype`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"age_n = age.astype(float)\n",
"print(age_n)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Esistono metodi ancora più raffinati come genfromtxt. Usate help(np.genfromtxt) oppure una ricerca sul web per ulteriori dettagli ed esempi"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"help(np.genfromtxt)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.genfromtxt(\"../Data/mixed_data.txt\", skip_header=2 , dtype=None, encoding=None,\n",
" names=('gender', 'weight', 'age'))\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Imparare Facendo
\n",
"\n",
"
Esaminate con un editor di testo o facendolo stampare in una finestra di comandi il contenuto del file \"../Data/Iris_Dataset.csv\".\n",
"
Leggete dal file \"../Data/Iris_Dataset.csv\" le cinque colonne di dati usando il metodo loadtxt.\n",
"\n",
"
Determinate il numero di dati con sepal.width compresi fra 6.2 cm e 7.3 cm.\n",
"
Determinare quante misurazioni si riferiscono ad esemplari della varietà \"Versicolor\".\n",
"
\n",
"
\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 7.2.10 Come esportare degli array in un file di testo\n",
"\n",
"Esempio usando gli array importati in precedenza:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"info = \"Misure esperimento Caduta Libera\\n\"\n",
"info +=\"Data: 13 Dicembre 2019\\n\"\n",
"info +=\"\\n\\n\"\n",
"info +=\" Punto Tempo(sec) Altezza(m) Incertezza(m)\\n\"\n",
"\n",
"np.savetxt('../ShellPrograms/CLD.txt',\n",
" list(zip(dataPt, time, height, error)),\n",
" header=info, fmt=\"%12.1f\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Se si preferisce un file CSV:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.savetxt('../ShellPrograms/CLD.csv',\n",
" list(zip(dataPt, time, height, error)),\n",
" header=info, fmt=\"%12.1f\", delimiter=\",\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La funzione `zip`, partendo da due o più oggetti iterabili (stringhe, liste, ntuple) di uguale lunghezza, restituisce un iteratore che combina\n",
"il contenuto degli oggetti di partenza. Per ottenere il risultato finale in un colpo solo, invece che un elemento alla volta, si passa l'iteratore generato da `zip` al comando `list`. \n",
"Esempi:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"l1 = [1,2,3]\n",
"l2 = ['a','b','c']\n",
"list(zip(l1,l2))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"l1 = 'pippo'\n",
"l2 = 'pluto'\n",
"list(zip(l1,l2))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"l1 = [1,2,3,4,5]\n",
"l2 = 'pluto'\n",
"list(zip(l1,l2))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Se i due oggetti hanno lunghezza diversa (pericoloso):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"l2 =['a']\n",
"list(zip(l1,l2))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Imparare Facendo
\n",
" \n",
"\n",
"
Create un array di 100 righe e due colonne che contenga nella prima colonna i numeri interi fra 1 e 100 e nella seconda i corrispondenti quadrati.\n",
"\n",
"
salvate i risultati nel file quadrati.txt con header la data odierna e la stringa numeri quadrati.\n",
"
In una finestra di comandi fate stampare il contenuto di quadrati.txt.\n",
"