Vai al contenuto principale

Scipy Tutorial: Vectors and Arrays (Linear Algebra)

Un tutorial su SciPy in cui imparerai le basi di algebra lineare necessarie per il machine learning in Python, con un focus sul come fare con NumPy.
Aggiornato 29 set 2026  · 15 min leggi

Scopri con l'IA

ChatGPTClaudePerplexity

Molto di ciò che devi sapere per addentrarti davvero nel machine learning è algebra lineare, ed è esattamente ciò che affronta questo tutorial. Il post di oggi passa in rassegna gli argomenti di algebra lineare che devi conoscere e comprendere per migliorare l’intuizione su come e quando funzionano i metodi di machine learning, guardando al livello di vettori e matrici.

Alla fine del tutorial, speriamo che ti senta più sicuro nell’analizzare più da vicino un algoritmo!

Contenuti


Introduzione

Uno dei tre argomenti fondamentali che devi padroneggiare se vuoi imparare la data science è il machine learning. E quando inizi davvero a occuparti di machine learning, è importante andare più a fondo e sviluppare intuizione e comprensione di come funzionano gli algoritmi.

E credo che tu, aspirante data scientist, sarai d’accordo con me quando dico che può essere difficile arrivare a questo punto.

Ma non deve esserlo.

SciPy vs NumPy

Dal tutorial su NumPy di DataCamp, avrai capito che questa libreria è una delle librerie core per il calcolo scientifico in Python. Contiene una raccolta di strumenti e tecniche che possono essere usati per risolvere al computer modelli matematici di problemi in Scienza e Ingegneria. Ma lo strumento che userai più spesso è un oggetto array multidimensionale ad alte prestazioni: è una potente struttura dati che consente di calcolare in modo efficiente array e matrici.

Ora, SciPy è fondamentalmente NumPy.

È anche uno dei pacchetti core per il calcolo scientifico che fornisce algoritmi matematici e funzioni di comodo, ma è costruito sull’estensione NumPy di Python. Questo significa che SciPy e NumPy vengono spesso usati insieme!

Più avanti in questo tutorial, ti sarà chiaro come la collaborazione tra queste due librerie sia diventata naturale.

Interagire con NumPy e SciPy

Per interagire in modo efficiente con entrambi i pacchetti, devi prima conoscere alcune basi di questa libreria e della sua potente struttura dati. Per lavorare con questi array, c’è una grande quantità di funzioni matematiche di alto livello che operano su matrici e array.

Di seguito troverai una rapida panoramica degli argomenti che devi padroneggiare per lavorare in modo efficiente con SciPy. In sostanza, devi conoscere la struttura degli array, come gestire i tipi di dato e come manipolare la forma degli array. Se questo ti suona alieno, valuta di seguire il Python NumPy Tutorial di DataCamp e, mentre impari, non dimenticare di dare un’occhiata al cheat sheet di NumPy.

Se sai già tutto questo, salta la sezione seguente e vai a “Algebra lineare con SciPy”, ma tieni a portata di mano il cheat sheet di SciPy per l’algebra lineare!

data science courses banner

Essenziali degli oggetti NumPy ndarray

Un array, strutturalmente parlando, non è altro che puntatori. È una combinazione di un indirizzo di memoria, un tipo di dato, una forma e stride. Contiene informazioni sui dati grezzi, su come localizzare un elemento e su come interpretarlo.

L’indirizzo di memoria e gli stride sono importanti quando vai più a fondo nei dettagli di basso livello degli array, mentre il tipo di dato e la forma sono cose che i principianti dovrebbero sicuramente conoscere e capire. Altri due attributi che potresti voler considerare sono data e size, che ti permettono di raccogliere ancora più informazioni sul tuo array.

Rinfresca l’uso degli attributi di ndarray nel seguente blocco DataCamp Light. L’array myArray è già stato caricato. Puoi ispezionarlo digitandolo nella shell IPython e premendo INVIO.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5teUFycmF5ID0gbnAuYXJyYXkoW1sxLDIsM10sWzQsNSw2XV0pIiwic2FtcGxlIjoiIyBJbnNwZWN0IHRoZSBkYXRhIG9mIGBteUFycmF5YFxucHJpbnQobXlBcnJheS5kYXRhKVxuXG4jIEluc3BlY3QgdGhlIGRhdGEgdHlwZSBvZiBgbXlBcnJheWBcbnByaW50KF9fX19fX19fX19fX19fX19fKVxuXG4jIEluc3BlY3QgdGhlIHNoYXBlIG9mIGBteUFycmF5YFxucHJpbnQoX19fX19fX19fX19fX19fX19fKVxuXG4jIEluc3BlY3QgdGhlIHNpemUgb2YgYG15QXJyYXlgXG5wcmludChfX19fX19fX19fX19fX19fX18pIiwic29sdXRpb24iOiIjIEluc3BlY3QgdGhlIGRhdGEgb2YgYG15QXJyYXlgXG5wcmludChteUFycmF5LmRhdGEpXG5cbiMgSW5zcGVjdCB0aGUgZGF0YSB0eXBlIG9mIGBteUFycmF5YFxucHJpbnQobXlBcnJheS5kdHlwZSlcblxuIyBJbnNwZWN0IHRoZSBzaGFwZSBvZiBgbXlBcnJheWBcbnByaW50KG15QXJyYXkuc2hhcGUpXG5cbiMgSW5zcGVjdCB0aGUgc2l6ZSBvZiBgbXlBcnJheWBcbnByaW50KG15QXJyYXkuc2l6ZSkiLCJzY3QiOiJ0ZXN0X2Z1bmN0aW9uKFxuICAgIFwicHJpbnRcIixcbiAgICAxLFxuICAgIG5vdF9jYWxsZWRfbXNnPVwiRGlkIHlvdSBwcmludCBvdXQgYG15QXJyYXkuZGF0YWA/XCIsXG4gICAgaW5jb3JyZWN0X21zZz1cIkRvbid0IGZvcmdldCB0byBwcmludCBvdXQgdGhlIGRhdGEgb2YgYG15QXJyYXlgIVwiLFxuICAgIGRvX2V2YWw9RmFsc2VcbilcbnRlc3RfZnVuY3Rpb24oXG4gICAgXCJwcmludFwiLFxuICAgIDIsXG4gICAgbm90X2NhbGxlZF9tc2c9XCJEaWQgeW91IHByaW50IG91dCBgbXlBcnJheS5kdHlwZWA/XCIsXG4gICAgaW5jb3JyZWN0X21zZz1cIkRvbid0IGZvcmdldCB0byBwcmludCBvdXQgdGhlIGRhdGEgdHlwZSBvZiBgbXlBcnJheWAhXCIsXG4gICAgZG9fZXZhbD1GYWxzZVxuKVxudGVzdF9mdW5jdGlvbihcbiAgICBcInByaW50XCIsXG4gICAgMyxcbiAgICBub3RfY2FsbGVkX21zZz1cIkRpZCB5b3UgcHJpbnQgb3V0IGBteUFycmF5LnNoYXBlYD9cIixcbiAgICBpbmNvcnJlY3RfbXNnPVwiRG9uJ3QgZm9yZ2V0IHRvIHByaW50IG91dCB0aGUgc2hhcGUgb2YgYG15QXJyYXlgIVwiLFxuICAgIGRvX2V2YWw9RmFsc2VcbilcbnRlc3RfZnVuY3Rpb24oXG4gICAgXCJwcmludFwiLFxuICAgIDQsXG4gICAgbm90X2NhbGxlZF9tc2c9XCJEaWQgeW91IHByaW50IG91dCB0aGUgYG15QXJyYXkuc2l6ZWA/XCIsXG4gICAgaW5jb3JyZWN0X21zZz1cIkRvbid0IGZvcmdldCB0byBwcmludCBvdXQgdGhlIHNpemUgb2YgYG15QXJyYXlgIVwiLFxuICAgIGRvX2V2YWw9RmFsc2VcbilcbnN1Y2Nlc3NfbXNnKFwiV2VsbCBkb25lIVwiKSJ9

Nei risultati del codice incluso nel blocco qui sopra vedrai che il tipo di dato di myArray è int64. Quando lavori intensamente con gli array, ti ricorderai sicuramente che esistono modi per convertire i tuoi array da un tipo di dato a un altro con il metodo astype().

Tuttavia, quando usi SciPy e NumPy insieme, potresti trovare molto utili anche le seguenti funzioni NumPy per la gestione dei tipi, soprattutto quando lavori con numeri complessi:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5teUFycmF5ID0gbnAuYXJyYXkoW1sxKzVqLDIsMys2al0sWzQrMWosNSw2KzJqXV0pIiwic2FtcGxlIjoiIyBSZXR1cm4gdGhlIHJlYWwgcGFydCBvZiBgbXlBcnJheWAgZWxlbWVudHNcbm5wLnJlYWwobXlBcnJheSlcblxuIyBSZXR1cm4gdGhlIGltYWdpbmFyeSBwYXJ0IG9mIGBteUFycmF5YCBlbGVtZW50c1xubnAuaW1hZyhteUFycmF5KVxuXG4jIFJldHVybiBhIHJlYWwgYXJyYXkgaWYgdGhlIGNvbXBsZXggcGFydHMgYXJlIGNsb3NlIHRvIDBcbm5wLnJlYWxfaWZfY2xvc2UobXlBcnJheSx0b2w9MTAwMClcblxuIyBDYXN0IGBteUFycmF5YCB0byBmbG9hdFxubnAuY2FzdFsnZiddKG15QXJyYXkpIn0=

Prova ad aggiungere chiamate a print() per vedere i risultati del codice qui sopra. Vedrai che i numeri complessi hanno una parte reale e una immaginaria. Le funzioni np.real() e np.imag() sono pensate per restituire rispettivamente queste parti all’utente.

In alternativa, puoi anche usare np.cast per effettuare il cast di un oggetto array a un tipo di dato diverso, come float nell’esempio sopra.

L’unica cosa che spicca davvero in termini di difficoltà nel blocco di codice sopra è la funzione np.real_if_close(). Quando le passi un input complesso, come myArray, ottieni indietro un array reale se le parti complesse sono vicine a zero. Quest’ultima parte, “vicine a 0”, può essere regolata con l’argomento tol che puoi passare alla funzione. Smanetta un po’ con la soglia per vedere cosa succede!

Creazione di array

Hai visto come ispezionare il tuo array e modificare il suo tipo di dato, ma non hai ancora visto esplicitamente come creare array. Dovresti già sapere che puoi usare np.array() per farlo, ma ci sono altre routine per la creazione di array che dovresti conoscere: np.eye() e np.identity().

La funzione np.eye() ti permette di creare una matrice quadrata con dimensioni pari all’intero positivo che passi come argomento alla funzione. Gli elementi sono generalmente riempiti di zeri, solo la diagonale della matrice è piena di uno. La funzione np.identity() funziona allo stesso modo e restituisce anch’essa un array identità.

Tuttavia, nota che np.eye() può accettare un argomento aggiuntivo k che puoi specificare per scegliere l’indice della diagonale che vuoi riempire di uno.

Altre funzioni per la creazione di array che torneranno sicuramente utili quando lavori con matrici per l’algebra lineare sono le seguenti:

  • La funzione np.arange() crea un array con valori equidistanti tra due numeri. Puoi specificare l’intervallo tra gli elementi,
  • Lo stesso vale per np.linspace(), ma con questa funzione specifichi il numero di elementi che vuoi nel tuo array.
  • Infine, la funzione np.logspace() crea anch’essa array con valori equidistanti, ma questa volta su scala logaritmica. Ciò significa che la spaziatura è ora logaritmica: due numeri sono equidistanti tra i logaritmi di questi due in base 10.

Queste funzioni creano array sotto forma di reticoli, che possono essere usati per creare mesh grid, di cui hai letto in precedenza in questo post.

Nota che numpy è già importato come np nel blocco di codice qui sotto!

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wIiwic2FtcGxlIjoiIyBDcmVhdGUgYSAyWDIgaWRlbnRpdHkgbWF0cml4IHdpdGggYG5wLmV5ZSgpYFxuX19fX19fX19fX19fX19fX19fXG5cbiMgQ3JlYXRlIGEgM1gzIGlkZW50aXR5IG1hdHJpeCB3aXRoIGBucC5pZGVudGl0eSgpYFxuX19fX19fX19fX19fX19fX19fXG5cbiMgVW5pZm9ybWx5IHNwYWNlZCB2YWx1ZXM6IHNwYWNpbmdcbl9fX19fX19fXygzLCA3LCAyKVxuXG4jIFVuaWZvcm1seSBzcGFjZWQgdmFsdWVzOiBudW1iZXIgb2Ygc2FtcGxlc1xuX19fX19fX19fX18oMiwgMywgNSlcblxuIyBVbmlmb3JtbHkgc3BhY2VkIHZhbHVlczogbG9nYXJpdGhtaWMgc3BhY2luZyBcbl9fX19fX19fX19fKDIsIDMsIDQpIiwic29sdXRpb24iOiIjIENyZWF0ZSBhIDJYMiBpZGVudGl0eSBtYXRyaXggd2l0aCBgbnAuZXllKClgXG5ucC5leWUoMilcblxuIyBDcmVhdGUgYSAzWDMgaWRlbnRpdHkgbWF0cml4IHdpdGggYG5wLmlkZW50aXR5KClgXG5ucC5pZGVudGl0eSgzKVxuXG4jIFVuaWZvcm1seSBzcGFjZWQgdmFsdWVzOiBzcGFjaW5nXG5ucC5hcmFuZ2UoMywgNywgMilcblxuIyBVbmlmb3JtbHkgc3BhY2VkIHZhbHVlczogbnVtYmVyIG9mIHNhbXBsZXNcbm5wLmxpbnNwYWNlKDIsIDMsIDUpXG5cbiMgVW5pZm9ybWx5IHNwYWNlZCB2YWx1ZXM6IGxvZ2FyaXRobWljIHNwYWNpbmcgXG5ucC5sb2dzcGFjZSgyLCAzLCA0KSIsInNjdCI6InRlc3RfZnVuY3Rpb24oXCJudW1weS5leWVcIiwgYXJncz1bMF0sIGluY29ycmVjdF9tc2c9XCJEaWQgeW91IHVzZSBgbnAuZXllKClgIHRvIGNyZWF0ZSBhIDJ4MiBpZGVudGl0eSBtYXRyaXg/XCIpXG50ZXN0X2Z1bmN0aW9uKFwibnVtcHkuaWRlbnRpdHlcIiwgYXJncz1bMF0sIGluY29ycmVjdF9tc2c9XCJEaWQgeW91IHVzZSBgbnAuaWRlbnRpdHkoKWAgdG8gY3JlYXRlIGEgM3gzIGlkZW50aXR5IG1hdHJpeD9cIilcbnRlc3RfZnVuY3Rpb24oXCJudW1weS5hcmFuZ2VcIilcbnRlc3RfZnVuY3Rpb24oXCJudW1weS5saW5zcGFjZVwiKVxudGVzdF9mdW5jdGlvbihcIm51bXB5LmxvZ3NwYWNlXCIpXG5zdWNjZXNzX21zZyhcIkdyZWF0IGpvYiFcIikifQ==

Ora che hai rinfrescato la memoria e sai come gestire i tipi di dato dei tuoi array, è il momento di affrontare anche l’indicizzazione e lo slicing.

Indicizzazione e slicing

Con l’indicizzazione, usi in pratica parentesi quadre [] per indicizzare i valori dell’array. In altre parole, puoi usare l’indicizzazione se vuoi accedere a elementi selezionati, un sottoinsieme, di un array. Lo slicing dei dati è molto simile al subsetting, ma puoi considerarlo un po’ più avanzato. Quando fai lo slicing di un array, non consideri solo valori particolari, ma lavori con “regioni” di dati anziché pure “posizioni”.

Rinfresca entrambi i concetti con i seguenti esempi di codice:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5teUFycmF5ID0gbnAuYXJyYXkoWzEsMiwzLDRdKVxubXlfMmRBcnJheSA9IG5wLmFycmF5KFtbMSwyLDMsNF0sIFs1LDYsNyw4XV0sIGR0eXBlPW5wLmludDY0KVxubXlfM2RBcnJheSA9IG5wLmFycmF5KFtbWzEsMiwzLDRdLCBbNSw2LDcsOF1dLCBbWzEsMiwzLDRdLCBbOSwxMCwxMSwxMl1dXSwgZHR5cGU9bnAuaW50NjQpIiwic2FtcGxlIjoiIyBTbGljZSBgbXlBcnJheWAgYXQgaW5kZXggMCBhbmQgMVxucHJpbnQoX19fX19fX19fX19fKVxuXG4jIFNsaWNlIGBteV8yZEFycmF5YCBhdCByb3cgMCBhbmQgMSwgY29sdW1uIDFcbnByaW50KF9fX19fX19fX19fX19fX18pXG5cbiMgU2xpY2UgYG15XzNkQXJyYXlgIGF0IHJvdyAxXG5wcmludChteV8zZEFycmF5WzEsLi4uXSlcblxuIyBCb29sZWFuIGluZGV4aW5nOiBvbmx5IHZhbHVlcyA8IDJcbnByaW50KG15QXJyYXlbX19fX19fX19fX19fXSlcblxuIyBGYW5jeSBpbmRleGluZ1xucHJpbnQobXlfMmRBcnJheVtbMSwgMCwgMSwgMF0sWzAsIDEsIDIsIDBdXSkiLCJzb2x1dGlvbiI6IiMgU2xpY2UgYG15QXJyYXlgIGF0IGluZGV4IDAgYW5kIDFcbnByaW50KG15QXJyYXlbMDoyXSlcblxuIyBTbGljZSBgbXlfMmRBcnJheWAgYXQgcm93IDAgYW5kIDEsIGNvbHVtbiAxXG5wcmludChteV8yZEFycmF5WzA6MiwxXSlcblxuIyBTbGljZSBgbXlfM2RBcnJheWAgYXQgcm93IDFcbnByaW50KG15XzNkQXJyYXlbMSwuLi5dKVxuXG4jIEJvb2xlYW4gaW5kZXhpbmc6IG9ubHkgdmFsdWVzIDwgMlxucHJpbnQobXlBcnJheVtteUFycmF5PDJdKVxuXG4jIEZhbmN5IGluZGV4aW5nXG5wcmludChteV8yZEFycmF5W1sxLCAwLCAxLCAwXSxbMCwgMSwgMiwgMF1dKSIsInNjdCI6InRlc3RfZnVuY3Rpb24oXG4gICAgXCJwcmludFwiLFxuICAgIDEsXG4gICAgbm90X2NhbGxlZF9tc2c9XCJEaWQgeW91IHByaW50IG91dCBgbXlBcnJheVswOjJdYD9cIixcbiAgICBpbmNvcnJlY3RfbXNnPVwiRG9uJ3QgZm9yZ2V0IHRvIHNsaWNlIGBteUFycmF5YCBhdCBpbmRleCAwIGFuZCAxIVwiLFxuICAgIGRvX2V2YWw9RmFsc2VcbilcbnRlc3RfZnVuY3Rpb24oXG4gICAgXCJwcmludFwiLFxuICAgIDIsXG4gICAgbm90X2NhbGxlZF9tc2c9XCJEaWQgeW91IHByaW50IG91dCBgbXlfMmRBcnJheVswOjIsMV1gP1wiLFxuICAgIGluY29ycmVjdF9tc2c9XCJEb24ndCBmb3JnZXQgdG8gc2xpY2UgYG15XzJkQXJyYXlgIGF0IGluZGV4IDAgYW5kIDEsIGNvbHVtbiAxIVwiLFxuICAgIGRvX2V2YWw9RmFsc2VcbilcbnRlc3RfZnVuY3Rpb24oXG4gICAgXCJwcmludFwiLFxuICAgIDMsXG4gICAgbm90X2NhbGxlZF9tc2c9XCJEaWQgeW91IHByaW50IG91dCBgbXlfM2RBcnJheVsxLC4uLl1gP1wiLFxuICAgIGluY29ycmVjdF9tc2c9XCJEb24ndCBmb3JnZXQgdG8gc2xpY2UgYG15XzNkQXJyYXlgIGF0IHJvdyAxIVwiLFxuICAgIGRvX2V2YWw9RmFsc2VcbilcbnRlc3RfZnVuY3Rpb24oXG4gICAgXCJwcmludFwiLFxuICAgIDQsXG4gICAgbm90X2NhbGxlZF9tc2c9XCJEaWQgeW91IHByaW50IG91dCBgbXlBcnJheVtteUFycmF5PDJdYD9cIixcbiAgICBpbmNvcnJlY3RfbXNnPVwiRG9uJ3QgZm9yZ2V0IHRvIGFkZCB0aGUgY29uZGl0aW9uIGBteUFycmF5PDJgIHRvIGBteUFycmF5YCFcIixcbiAgICBkb19ldmFsPUZhbHNlXG4pXG50ZXN0X2Z1bmN0aW9uKFxuICAgIFwicHJpbnRcIixcbiAgICA1LFxuICAgIG5vdF9jYWxsZWRfbXNnPVwiRGlkIHlvdSBwcmludCBvdXQgYG15XzJkQXJyYXlbWzEsIDAsIDEsIDBdLFswLCAxLCAyLCAwXV1gP1wiLFxuICAgIGRvX2V2YWw9RmFsc2VcbilcbnN1Y2Nlc3NfbXNnKFwiWWF5ISBZb3UncmUgYW4gZXhwZXJ0IGluIGluZGV4aW5nIGFuZCBzbGljaW5nIHdpdGggTnVtUHkhXCIpIn0=

Ora che hai la mente fresca con slicing e indicizzazione, potresti essere interessato anche a qualche trucco di indicizzazione che può rendere il tuo lavoro più efficiente quando fai calcolo scientifico con SciPy. Ci sono quattro funzioni che incontrerai sicuramente: np.mgrid(), np.ogrid(), np.r e np.c.

Potresti già conoscere le ultime due se hai un po’ di esperienza con NumPy. np.r e np.c sono spesso usate quando devi impilare array per righe o per colonne, rispettivamente. Con queste funzioni puoi costruire rapidamente array invece di usare la funzione np.concatenate().

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5hcnJheSA9IG5wLmV5ZSgyKVxubXlfMmRBcnJheSA9IG5wLmFycmF5KFtbMSwyLDMsNF0sIFs1LDYsNyw4XV0sIGR0eXBlPW5wLmludDY0KSIsInNhbXBsZSI6IiMgQ3JlYXRlIGEgZGVuc2UgbWVzaGdyaWRcbm5wLm1ncmlkWzE6MTE6MiwgLTEyOi0zOjNdXG5cbiMgQ3JlYXRlIGFuIG9wZW4gbWVzaGdyaWRcbm5wLm9ncmlkWzE6MTE6MiwgLTEyOi0zOjNdXG5cbiMgU3RhY2sgYXJyYXlzIHZlcnRpY2FsbHlcbm5wLnJfWzMsWzBdKjUsLTE6MToxMGpdXG5cbiMgU3RhY2sgYXJyYXlzIGhvcml6b250YWxseSBcbm5wLmNfW2FycmF5LCBteV8yZEFycmF5XSJ9

Guardando alle prime due di queste quattro funzioni, potresti chiederti perché ti serva una meshgrid. Puoi usare le meshgrid per generare due array contenenti le coordinate x e y in ogni posizione di una griglia rettilinea. La funzione np.meshgrid() prende due array 1D e produce due matrici 2D corrispondenti a tutte le coppie (x, y) nei due array.

  • La funzione np.mgrid() è un’implementazione della meshgrid di MATLAB e restituisce array che hanno la stessa forma. Significa che le dimensioni e il numero degli array in output sono uguali al numero di dimensioni di indicizzazione.
  • La funzione np.ogrid(), invece, dà una open meshgrid e non è densa come il risultato che restituisce np.mgrid(). Puoi vedere la differenza visiva tra le due nel blocco di codice sopra.

Puoi anche leggere di più sulle differenze tra queste due funzioni qui.

Un’altra funzione che potresti usare per scopi di indicizzazione/slicing è np.select(). Puoi usarla per restituire valori da una lista di array in base a condizioni, che puoi specificare tu stesso nel primo argomento della funzione. Nel secondo argomento, passi l’array che vuoi considerare per questo processo di selezione.

Dai un’occhiata al seguente esempio:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wIiwic2FtcGxlIjoiIyBJbml0aWFsaXplIGEgMkQgYXJyYXkgXG5teV8yZEFycmF5ID0gbnAuYXJyYXkoW1sxLDIsMyw0XSwgWzUsNiw3LDhdXSwgZHR5cGU9bnAuaW50NjQpXG5cbiMgU2VsZWN0IHZhbHVlcyBmcm9tIGBteV8yZEFycmF5YFxubnAuc2VsZWN0KFtteV8yZEFycmF5IDwgNF0sW215XzJkQXJyYXkgKiAyXSkifQ==

Fantastico! Ora che hai selezionato i valori giusti del tuo array originale, puoi ancora selezionare la forma e manipolare il tuo nuovo array.

Selezione e manipolazione della forma

NumPy offre molti modi per selezionare e manipolare la forma dei tuoi array e probabilmente ne conosci già parecchi. La sezione seguente fornirà solo una breve panoramica delle funzioni che potrebbero tornare utili, quindi il post non le coprirà tutte.

Esistono funzioni “utili” quando lavori con SciPy?

Beh, le più utili sono quelle che ti aiutano ad appiattire gli array, impilarli e dividerli. Hai già visto le funzioni np.c e np.r che spesso preferirai a np.concatenate(), ma ce ne sono molte altre che vale la pena conoscere!

Come np.hstack() per impilare orizzontalmente i tuoi array o np.vstack() per impilarli verticalmente. Allo stesso modo, puoi usare np.vsplit() e np.hsplit() per dividere i tuoi array verticalmente e orizzontalmente. Ma probabilmente tutto questo lo sai già.

Dimostralo nel seguente blocco di codice:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5teUFycmF5ID0gbnAuYXJyYXkoWzEsMiwzLDRdKVxubXlfMmRBcnJheSA9IG5wLmFycmF5KFtbMSwyLDMsNF0sIFs1LDYsNyw4XV0sIGR0eXBlPW5wLmludDY0KVxubXlfM2RBcnJheSA9IG5wLmFycmF5KFtbWzEsMiwzLDRdLCBbNSw2LDcsOF1dLCBbWzEsMiwzLDRdLCBbOSwxMCwxMSwxMl1dXSwgZHR5cGU9bnAuaW50NjQpIiwic2FtcGxlIjoiI1N0YWNrIGFycmF5cyBob3Jpem9udGFsbHkgKGNvbHVtbi13aXNlKVxucHJpbnQoX19fX19fX19fKChucC5leWUoMiksIG15XzJkQXJyYXkpKSlcblxuIyBTdGFjayBhcnJheXMgdmVydGljYWxseSAocm93LXdpc2UpXG5wcmludChfX19fX19fX19fKChteUFycmF5LCBteV8yZEFycmF5KSkpXG5cbiMgU3BsaXQgdGhlIGFycmF5IGhvcml6b250YWxseSBhdCB0aGUgMm5kIGluZGV4XG5wcmludChfX19fX19fX19fXyhteV8yZEFycmF5LCAyKSlcblxuIyBTcGxpdCB0aGUgYXJyYXkgdmVydGljYWxseSBhdCB0aGUgMm5kIGluZGV4XG5wcmludChfX19fX19fX19fX18obXlfMmRBcnJheSwgMikpIiwic29sdXRpb24iOiIjU3RhY2sgYXJyYXlzIGhvcml6b250YWxseSAoY29sdW1uLXdpc2UpXG5wcmludChucC5oc3RhY2soKG5wLmV5ZSgyKSwgbXlfMmRBcnJheSkpKVxuXG4jIFN0YWNrIGFycmF5cyB2ZXJ0aWNhbGx5IChyb3ctd2lzZSlcbnByaW50KG5wLnZzdGFjaygobXlBcnJheSwgbXlfMmRBcnJheSkpKVxuXG4jIFNwbGl0IHRoZSBhcnJheSBob3Jpem9udGFsbHkgYXQgdGhlIDJuZCBpbmRleFxucHJpbnQobnAuaHNwbGl0KG15XzJkQXJyYXksIDIpKVxuXG4jIFNwbGl0IHRoZSBhcnJheSB2ZXJ0aWNhbGx5IGF0IHRoZSAybmQgaW5kZXhcbnByaW50KG5wLnZzcGxpdChteV8yZEFycmF5LCAyKSkiLCJzY3QiOiJ0ZXN0X2Z1bmN0aW9uKFxuICAgIFwicHJpbnRcIixcbiAgICAxLFxuICAgIG5vdF9jYWxsZWRfbXNnPVwiRGlkIHlvdSBwcmludCBvdXQgYG5wLmhzdGFjaygobnAuZXllKDIpLCBteV8yZEFycmF5KSlgP1wiLFxuICAgIGluY29ycmVjdF9tc2c9XCJEb24ndCBmb3JnZXQgdG8gc3RhY2sgYG5wLmV5ZSgyKWAgYW5kIGBteV8yZEFycmF5YCBob3Jpem9udGFsbHkhXCIsXG4gICAgZG9fZXZhbD1GYWxzZVxuKVxudGVzdF9mdW5jdGlvbihcbiAgICBcInByaW50XCIsXG4gICAgMixcbiAgICBub3RfY2FsbGVkX21zZz1cIkRpZCB5b3UgcHJpbnQgb3V0IGBucC52c3RhY2sobXlBcnJheSwgbXlfMmRBcnJheSkpYD9cIixcbiAgICBpbmNvcnJlY3RfbXNnPVwiRG9uJ3QgZm9yZ2V0IHRvIHN0YWNrIGBteUFycmF5YCBhbmQgYG15XzJkQXJyYXlgIHZlcnRpY2FsbHkhXCIsXG4gICAgZG9fZXZhbD1GYWxzZVxuKVxudGVzdF9mdW5jdGlvbihcbiAgICBcInByaW50XCIsXG4gICAgMyxcbiAgICBub3RfY2FsbGVkX21zZz1cIkRpZCB5b3UgcHJpbnQgb3V0IGBucC5oc3BsaXQobXlfMmRBcnJheSwgMilgP1wiLFxuICAgIGluY29ycmVjdF9tc2c9XCJEb24ndCBmb3JnZXQgdG8gaG9yaXpvbnRhbGx5IHNwbGl0IGBteV8yZEFycmF5YCBhdCB0aGUgMm5kIGluZGV4IVwiLFxuICAgIGRvX2V2YWw9RmFsc2VcbilcbnRlc3RfZnVuY3Rpb24oXG4gICAgXCJwcmludFwiLFxuICAgIDQsXG4gICAgbm90X2NhbGxlZF9tc2c9XCJEaWQgeW91IHByaW50IG91dCBgbnAudnNwbGl0KG15XzJkQXJyYXksIDIpYD9cIixcbiAgICBpbmNvcnJlY3RfbXNnPVwiRG9uJ3QgZm9yZ2V0IHRvIHZlcnRpY2FsbHkgc3BsaXQgYG15XzJkQXJyYXlgIGF0IGluZGV4IDIhXCIsXG4gICAgZG9fZXZhbD1GYWxzZVxuKVxuc3VjY2Vzc19tc2coXCJZb3UncmUgYSB0cnVlIG1hc3RlciBpbiBzdGFja2luZyBhbmQgc3BsaXR0aW5nIGFycmF5cyFcIikifQ==

Ricorda che la funzione np.eye() crea un array identità 2x2, perfetto da impilare con l’array 2-D che è stato caricato per te nel blocco di codice sopra.

Se vuoi sapere di più sulle condizioni da considerare quando vuoi impilare array, vai qui. Tuttavia, puoi anche limitarti a guardare gli array e cosa fanno le funzioni per farti un’intuizione delle “regole” da rispettare se vuoi unire i due array per riga o per colonna.

La cosa più importante da considerare quando dividi array è probabilmente la forma del tuo array, perché vuoi selezionare l’indice corretto in cui far avvenire la divisione.

Oltre alle routine per impilare e dividere array, tieni a mente che sono indispensabili anche le funzioni che aiutano a garantire che tu stia lavorando con array di una certa dimensione quando vai più in profondità nel calcolo scientifico.

Considera le seguenti funzioni:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5teUFycmF5ID0gbnAuYXJyYXkoWzEsMiwzLDRdKVxubXlfMmRBcnJheSA9IG5wLmFycmF5KFtbMSwyLDMsNF0sIFs1LDYsNyw4XV0sIGR0eXBlPW5wLmludDY0KVxubXlfM2RBcnJheSA9IG5wLmFycmF5KFtbWzEsMiwzLDRdLCBbNSw2LDcsOF1dLCBbWzEsMiwzLDRdLCBbOSwxMCwxMSwxMl1dXSwgZHR5cGU9bnAuaW50NjQpIiwic2FtcGxlIjoiI1Blcm11dGUgYG15QXJyYXlgIGRpbWVuc2lvbnNcbnByaW50KG5wLnRyYW5zcG9zZShteUFycmF5KSlcblxuIyBGbGF0dGVuIGBteV8zZEFycmF5YFxucHJpbnQobXlfM2RBcnJheS5mbGF0dGVuKCkpXG5cbiMgUmVzaGFwZSBidXQgZG9uJ3QgY2hhbmdlIHRoZSBkYXRhXG5wcmludChteV8yZEFycmF5LnJlc2hhcGUoNCwyKSlcblxuIyBSZXNpemUgdG8gKDYsNClcbnByaW50KG5wLnJlc2l6ZShteV8zZEFycmF5LCAoNiw0KSkpIn0=

Nota la differenza tra il cambiare forma (reshape) e il ridimensionare (resize) l’array. Con il primo, cambi la forma dei dati ma non cambi i dati stessi. Con il resize, è possibile che i dati contenuti nell’array cambino, a seconda della forma che selezioni, ovviamente.

Oltre alle routine di divisione e impilamento e alle funzioni che ti permettono di manipolare ulteriormente i tuoi array, c’è anche qualcosa come la “vettorializzazione” da considerare. Quando applichi una funzione a un array, di solito la applichi a ogni elemento dell’array. Considera, per esempio, l’applicazione di np.cos(), np.sin() o np.tan() a un array. Vedrai che funziona su tutti gli elementi dell’array. Quando vedi questo, sai che la funzione è vettorializzata.

Ma quando definisci funzioni da solo, come probabilmente farai quando ti avvicini al calcolo scientifico, potresti volerle vettorializzare. In questi casi, puoi chiamare np.vectorize():

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5teUFycmF5ID0gbnAuYXJyYXkoWzEsMiwzLDRdKSIsInNhbXBsZSI6IiMgRGVmaW5lIGEgZnVuY3Rpb24gYG15ZnVuY2BcbmRlZiBteWZ1bmMoYSxiKTpcbiAgaWYgYSA+IGI6XG4gICAgIHJldHVybiBhIC0gYlxuICBlbHNlOlxuICAgICByZXR1cm4gYSArIGJcbiAgICBcbiMgVmVjdG9yaXplIGBteWZ1bmNgXG52ZWN0b3JpemVkRnVuYyA9IG5wLnZlY3Rvcml6ZShteWZ1bmMpIFxuXG4jIEFwcGx5IFxudmVjdG9yaXplZEZ1bmMobXlBcnJheSwgMikifQ==

Per quanto riguarda altre funzioni matematiche vettorializzate che potresti voler conoscere, considera np.angle() per fornire l’angolo degli elementi complessi dell’array, ma torneranno utili anche le funzioni trigonometriche di base, esponenziali o logaritmiche.

Learn Python for Data Science With DataCamp

Algebra lineare con SciPy

Ora che sai cosa ti serve per usare entrambi i pacchetti a tuo vantaggio, è il momento di entrare nell’argomento di questo tutorial: l’algebra lineare.

Ma prima di vedere come usare Python, assicurati che il tuo ambiente di lavoro sia completamente pronto!

Installa SciPy

Ovviamente devi prima assicurarti di avere installato Python. Vai a questa pagina se devi ancora farlo :) Se lavori su Windows, assicurati di aver aggiunto Python alla variabile di ambiente PATH environment variable. Inoltre, non dimenticare di installare un package manager, come pip, che ti permetterà di usare le librerie open source di Python.

Nota che le versioni recenti di Python 3 includono pip, quindi verifica se ce l’hai e, se sì, aggiornalo prima di installare altri pacchetti:

 pip install pip --upgrade pip --version

Ma installare un package manager non basta; Devi anche scaricare la wheel della libreria: vai qui per ottenere la wheel di SciPy. Dopo il download, apri il terminale nella cartella di download sul tuo PC e installala. Inoltre, puoi verificare se l’installazione è andata a buon fine e confermare la versione del pacchetto che stai usando:

# Install the wheel install "scipy‑0.18.1‑cp36‑cp36m‑win_amd64.whl"# Confirm successful installimport scipy# Check package versionscipy.__version__

Dopo questi passaggi, sei pronto a partire!

Consiglio: installa il pacchetto scaricando la distribuzione Anaconda di Python. È un modo semplice per iniziare rapidamente, perché Anaconda non solo include 100 dei più popolari pacchetti Python, R e Scala per la data science, ma include anche diversi ambienti di sviluppo open source come Jupyter e Spyder. Se vuoi iniziare a lavorare con Jupyter Notebook, dai un’occhiata a questo tutorial su Jupyter notebook.

Se non l’hai ancora scaricato, vai qui per ottenerlo.

Vettori e matrici: le basi

Ora che ti sei assicurato che il tuo ambiente di lavoro sia pronto, puoi finalmente iniziare con l’algebra lineare in Python. In sostanza, questa disciplina si occupa dello studio degli spazi vettoriali e delle applicazioni lineari che esistono tra di essi. Queste applicazioni lineari possono essere descritte con matrici, il che rende anche più facile il calcolo.

Ricorda che uno spazio vettoriale è un concetto fondamentale dell’algebra lineare. È uno spazio in cui hai una collezione di oggetti (vettori) e in cui puoi sommare o scalare due vettori senza che il vettore risultante esca dallo spazio. Ricorda anche che i vettori sono righe (o colonne) di una matrice.

Ma come funziona in Python?

Puoi creare facilmente un vettore con la funzione np.array(). Allo stesso modo, puoi dare una struttura di matrice a qualsiasi ndarray monodimensionale o bidimensionale con i comandi np.matrix() o np.mat().

Provalo nel seguente blocco di codice:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wIiwic2FtcGxlIjoiIyBDcmVhdGUgYSB2ZWN0b3Jcbm15VmVjdG9yID0gbnAuYXJyYXkoWzEsMiwzLDRdKVxuXG4jIENyZWF0ZSBhIG1hdHJpeFxubXlNYXRyaXggPSBucC5tYXRyaXgobnAucmFuZG9tLnJhbmRvbSgoNSw1KSkpIn0=

Quindi array e matrici sono la stessa cosa, a parte la formattazione?

Beh, non proprio. Ci sono alcune differenze:

  • Una matrice è 2-D, mentre gli array sono di solito n-D,
  • Come implicano le funzioni sopra, la matrice è una sottoclasse di ndarray,
  • Sia gli array che le matrici hanno .T(), ma solo le matrici hanno .H() e .I(),
  • La moltiplicazione tra matrici funziona in modo diverso dalla moltiplicazione elemento per elemento degli array, e
  • Inoltre, l’operazione ** produce risultati diversi per matrici e array

Quando lavori con le matrici, potresti talvolta averne alcune in cui la maggior parte degli elementi è zero. Queste matrici sono chiamate “matrici sparse”, mentre quelle con per lo più elementi diversi da zero sono dette “dense”.

Di per sé, sembra banale, ma quando lavori con SciPy per l’algebra lineare, questo può a volte fare la differenza nei moduli che usi per svolgere certe operazioni. Più concretamente, puoi usare scipy.linalg per matrici dense, ma quando lavori con matrici sparse, potresti anche considerare di consultare il modulo scipy.sparse, che contiene anche il proprio scipy.sparse.linalg.

Per le matrici sparse, ci sono diverse opzioni per crearle. Il blocco di codice sotto ne elenca alcune:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5mcm9tIHNjaXB5IGltcG9ydCBzcGFyc2UgXG5DID0gbnAucmFuZG9tLnJhbmRvbSgoMTAsNSkpXG5DW0MgPiAwLjVdID0gMCAiLCJzYW1wbGUiOiIjIENyZWF0ZSBhIDJYMiBpZGVudGl0eSBtYXRyaXhcbm5wLmV5ZSgzLCBrPTEpICAgICAgICBcblxuIyBDcmVhdGUgYSAyeDIgaWRlbnRpdHkgbWF0cml4XG5ucC5tYXQobnAuaWRlbnRpdHkoMikpICAgICAgICAgXG5cbiMgQ29tcHJlc3NlZCBTcGFyc2UgUm93IG1hdHJpeFxuc3BhcnNlLmNzcl9tYXRyaXgoQykgIFxuXG4jIENvbXByZXNzZWQgU3BhcnNlIENvbHVtbiBtYXRyaXhcbnNwYXJzZS5jc2NfbWF0cml4KEMpICBcblxuIyBEaWN0aW9uYXJ5IE9mIEtleXMgbWF0cml4XG5zcGFyc2UuZG9rX21hdHJpeChDKSAgIn0=

Inoltre, esistono anche altre funzioni che potresti usare per creare matrici sparse: matrici Block Sparse Row con bsr_matrix(), matrici sparse in formato COOrdinate con coo_matrix(), matrici sparse con storage DIAgonal con dia_matrix() e matrici sparse basate su liste collegate per righe con lil_matrix().

Le opzioni sono davvero molte, ma quale dovresti scegliere se stai creando una matrice sparsa tu stesso?

Non è così difficile.

Fondamentalmente, dipende innanzitutto da come la inizializzerai. Poi, considera cosa vuoi fare con la tua matrice sparsa.

Più concretamente, puoi seguire la seguente checklist per decidere che tipo di matrice sparsa usare:

  • Se prevedi di riempire la matrice numero per numero, scegli coo_matrix() o dok_matrix() per creare la matrice.
  • Se vuoi inizializzare la matrice con un array come diagonale, scegli dia_matrix() per inizializzarla.
  • Per matrici basate su slicing, usa lil_matrix().
  • Se stai costruendo la matrice a partire da blocchi di matrici più piccole, considera bsr_matrix().
  • Se vuoi un accesso veloce a righe e colonne, converti le matrici usando rispettivamente le funzioni csr_matrix() e csc_matrix(). Le ultime due non sono ideali per l’inizializzazione, ma quando moltiplichi noterai decisamente la differenza di velocità.

Fatto!

Operazioni sui vettori

Ora che hai imparato o ripassato la differenza tra vettori, matrici dense e matrici sparse, è il momento di dare uno sguardo più da vicino ai vettori e al tipo di operazioni matematiche che puoi fare con essi. Il tutorial qui si concentra esplicitamente sulle operazioni matematiche, così vedrai similitudini e differenze con le matrici, e perché gran parte dell’algebra lineare è, in definitiva, lavorare con matrici.

Hai già visto che puoi creare facilmente un vettore con np.array(). Ma ora che hai i vettori a disposizione, potresti voler conoscere alcune operazioni di base che puoi eseguire su di essi. vector1 e vector2 sono già caricati per te nel seguente blocco di codice:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG52ZWN0b3IxPW5wLmFycmF5KFsxLDIsM10pXG52ZWN0b3IyID0gbnAuYXJyYXkoWzIsMyw0XSkiLCJzYW1wbGUiOiIjIEFkZGl0aW9uIG9mIGB2ZWN0b3IxYCBhbmQgYHZlY3RvcjJgXG52ZWN0b3IzID0gdmVjdG9yMSArIHZlY3RvcjJcblxuIyBQcmludCBgdmVjdG9yM2BcbnByaW50KF9fX19fX18pXG5cbiMgU3VidHJhY3Rpb24gb2YgYHZlY3RvcjJgIGFuZCBgdmVjdG9yMWBcbnZlY3RvcjQgPSBfX19fX19fXyAtIHZlY3RvcjFcblxuIyBwcmludCBgdmVjdG9yNGBcbnByaW50KHZlY3RvcjQpXG5cbiMgRG90IHByb2R1Y3Qgb2YgYHZlY3RvcjFgIGFuZCBgdmVjdG9yMmBcbmRvdFByb2R1Y3QgPSBucC5kb3QodmVjdG9yMSwgdmVjdG9yMilcblxuIyBQcmludCBgZG90UHJvZHVjdGBcbnByaW50KGRvdFByb2R1Y3QpXG5cbiMgQ3Jvc3MgcHJvZHVjdCBvZiBgdmVjdG9yMWAgYW5kIGB2ZWN0b3IyYFxuY3Jvc3NQcm9kdWN0ID0gbnAuY3Jvc3MoX19fX19fX18sIHZlY3RvcjIpXG5cbiMgUHJpbnQgYGNyb3NzUHJvZHVjdGBcbnByaW50KF9fX19fX19fX19fXykiLCJzb2x1dGlvbiI6IiMgQWRkaXRpb24gb2YgYHZlY3RvcjFgIGFuZCBgdmVjdG9yMmBcbnZlY3RvcjMgPSB2ZWN0b3IxICsgdmVjdG9yMlxuXG4jIFByaW50IGB2ZWN0b3IzYCBvZiBgdmVjdG9yMmAgYW5kIGB2ZWN0b3IxYFxucHJpbnQodmVjdG9yMylcblxuIyBTdWJ0cmFjdGlvblxudmVjdG9yNCAgPSB2ZWN0b3IyIC0gdmVjdG9yMVxuXG4jIHByaW50IGB2ZWN0b3I0YFxucHJpbnQodmVjdG9yNClcblxuIyBEb3QgcHJvZHVjdCBvZiBgdmVjdG9yMWAgYW5kIGB2ZWN0b3IyYFxuZG90UHJvZHVjdCA9IG5wLmRvdCh2ZWN0b3IxLCB2ZWN0b3IyKVxuXG4jIFByaW50IGBkb3RQcm9kdWN0YFxucHJpbnQoZG90UHJvZHVjdClcblxuIyBDcm9zcyBwcm9kdWN0IG9mIGB2ZWN0b3IxYCBhbmQgYHZlY3RvcjJgXG5jcm9zc1Byb2R1Y3QgPSBucC5jcm9zcyh2ZWN0b3IxLCB2ZWN0b3IyKVxuXG4jIFByaW50IGBjcm9zc1Byb2R1Y3RgXG5wcmludChjcm9zc1Byb2R1Y3QpIiwic2N0IjoidGVzdF9vYmplY3QoXCJ2ZWN0b3IzXCIpXG50ZXN0X2Z1bmN0aW9uKFwicHJpbnRcIiwgaW5kZXg9MSlcbnRlc3Rfb2JqZWN0KFwidmVjdG9yNFwiLCBpbmRleD0yKVxudGVzdF9mdW5jdGlvbihcInByaW50XCIsIGluZGV4PTIpXG50ZXN0X29iamVjdF9hY2Nlc3NlZChcImRvdFByb2R1Y3RcIilcbnRlc3RfZnVuY3Rpb24oXCJwcmludFwiLCBpbmRleD0zKVxudGVzdF9vYmplY3QoXCJjcm9zc1Byb2R1Y3RcIilcbnRlc3RfZnVuY3Rpb24oXCJwcmludFwiLCBpbmRleD00KVxuc3VjY2Vzc19tc2coXCJXZWxsIGRvbmUhXCIpIn0=

Ora che hai visto con successo alcune operazioni sui vettori, è il momento di passare al vero lavoro con le matrici!

Matrici: operazioni e routine

Analogamente a dove avevi lasciato all’inizio della sezione precedente, sai come creare matrici, ma non sai ancora come usarle a tuo vantaggio. Questa sezione ti fornirà una panoramica di alcune funzioni e routine di base sulle matrici che puoi usare per lavorare in modo efficiente.

Per prima cosa, passiamo in rassegna alcune funzioni. Se hai già lavorato con NumPy ti verranno abbastanza facili, ma anche se non hai ancora esperienza vedrai che sono semplici da usare.

Vediamo alcuni esempi di funzioni.

Ci sono np.add() e np.subtract() per sommare e sottrarre array o matrici, e anche np.divide() e np.multiply per divisione e moltiplicazione. Non sembra un grande mistero, vero? Anche la funzione np.dot() che hai visto nella sezione precedente, dove veniva usata per calcolare il prodotto scalare, può essere usata con le matrici. Ma non dimenticare di passare due matrici invece di vettori.

Queste sono basilari, giusto?

Andiamo un po’ oltre. Per quanto riguarda le moltiplicazioni, ci sono anche altre funzioni da considerare, come np.vdot() per il prodotto scalare di vettori, np.inner() o np.outer() per i prodotti interno o esterno di array, np.tensordot() e np.kron() per il prodotto di Kronecker di due array:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5tYXRyaXgxID0gbnAubWF0cml4KG5wLnJhbmRvbS5yYW5kb20oKDIsMikpKVxubWF0cml4MiA9IG5wLm1hdChbWzMsNF0sIFs1LDZdXSlcbnZlY3RvcjE9bnAuYXJyYXkoWzEsMiwzXSlcbnZlY3RvcjIgPSBucC5hcnJheShbMiwzLDRdKSIsInNhbXBsZSI6IiMgVmVjdG9yIGRvdCBwcm9kdWN0XG52ZWN0b3JEb3RQcm9kdWN0ID0gbnAudmRvdCh2ZWN0b3IxLCB2ZWN0b3IyKVxuXG4jIElubmVyIHByb2R1Y3RcbmlubmVyUHJvZHVjdCA9IG5wLmlubmVyKHZlY3RvcjEsIHZlY3RvcjIpXG5cbiMgT3V0ZXIgcHJvZHVjdFxub3V0ZXJQcm9kdWN0ID0gbnAub3V0ZXIodmVjdG9yMSwgdmVjdG9yMilcblxuIyBUZW5zb3IgZG90IHByb2R1Y3RcbnRlbnNvckRvdFByb2R1Y3QgPSBucC50ZW5zb3Jkb3QobWF0cml4MSwgbWF0cml4MilcblxuIyBLcm9uZWNrZXIgcHJvZHVjdFxua3JvblByb2R1Y3QgPSBucC5rcm9uKG1hdHJpeDEsIG1hdHJpeDIpIn0=

Consiglio: aggiungi delle istruzioni di stampa al blocco di codice qui sopra per vedere i risultati dei singoli prodotti.

Oltre a queste, potrebbe essere utile considerare alcune funzioni del modulo linalg: le funzioni esponenziali di matrice linalg.expm(), linalg.expm2() e linalg.expm3(). La differenza tra queste tre sta nei modi in cui viene calcolata l’esponenziale. Attieniti alla prima per un’esponenziale di matrice generale, ma prova sicuramente tutte e tre per vedere la differenza nei risultati!

Inoltre, ci sono funzioni trigonometriche come linalg.cosm(), linalg.sinm() e linalg.tanm(), funzioni trigonometriche iperboliche come linalg.coshm(), linalg.sinhm() e linalg.tanhm(), la funzione segno linalg.signm(), il logaritmo di matrice linalg.logm() e la radice quadrata di matrice linalg.sqrtm().

Inoltre, puoi anche valutare una funzione di matrice con l’aiuto della funzione linalg.funm(). Guarda l’esempio qui sotto:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiZnJvbSBzY2lweSBpbXBvcnQgbGluYWxnXG5pbXBvcnQgbnVtcHkgYXMgbnAgXG5teU1hdHJpeCA9IG5wLm1hdHJpeChucC5yYW5kb20ucmFuZG9tKCg1LDUpKSkiLCJzYW1wbGUiOiJsaW5hbGcuZnVubShteU1hdHJpeCwgbGFtYmRhIHg6IHgqeCkifQ==

Vedi che passi come primo argomento la matrice a cui vuoi applicare una funzione e come secondo argomento una funzione (in questo caso una funzione lambda) che vuoi applicare alla matrice passata. Nota che la funzione che passi a linalg.funm() deve essere vettorializzata.

Vediamo ora alcune routine di base sulle matrici. La prima cosa che probabilmente vorrai provare sono gli attributi della matrice: T per la trasposizione, H per la trasposizione coniugata, I per l’inversa e A per effettuare il cast ad array.

Provali:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wIFxubXlNYXRyaXggPSBucC5tYXRyaXgobnAucmFuZG9tLnJhbmRvbSgoNSw1KSkpIiwic2FtcGxlIjoiIyBUcmFuc3Bvc2l0aW9uXG5teU1hdHJpeC5fXG5cbiMgQ29uanVnYXRlIHRyYW5zcG9zaXRpb25cbm15TWF0cml4Ll9cblxuIyBJbnZlcnNlXG5teU1hdHJpeC5fXG5cbiMgQXJyYXlcbm15TWF0cml4Ll8iLCJzb2x1dGlvbiI6IiMgVHJhbnNwb3NpdGlvblxubXlNYXRyaXguVFxuXG4jIENvbmp1Z2F0ZSB0cmFuc3Bvc2l0aW9uXG5teU1hdHJpeC5IXG5cbiMgSW52ZXJzZVxubXlNYXRyaXguSVxuXG4jIEFycmF5XG5teU1hdHJpeC5BIiwic2N0IjoidGVzdF9vYmplY3RfYWNjZXNzZWQoXCJteU1hdHJpeC5UXCIpXG50ZXN0X29iamVjdF9hY2Nlc3NlZChcIm15TWF0cml4LkhcIilcbnRlc3Rfb2JqZWN0X2FjY2Vzc2VkKFwibXlNYXRyaXguSVwiKVxudGVzdF9vYmplY3RfYWNjZXNzZWQoXCJteU1hdHJpeC5BXCIpXG5zdWNjZXNzX21zZyhcIkF3ZXNvbWUhXCIpIn0=

Quando trasponi una matrice, crei una nuova matrice le cui righe sono le colonne dell’originale. Una trasposizione coniugata, invece, scambia l’indice di riga e colonna per ogni elemento della matrice. L’inversa di una matrice è una matrice che, se moltiplicata per la matrice originale, risulta in una matrice identità.

Ma oltre a questi attributi, ci sono anche funzioni vere e proprie che puoi usare per eseguire alcune routine di base sulle matrici, come np.transpose() e linalg.inv() rispettivamente per trasposizione e inversa.

Oltre a queste, puoi anche recuperare la traccia, ossia la somma degli elementi sulla diagonale principale della matrice, con np.trace(). Allo stesso modo, puoi anche recuperare il rango della matrice o il numero di valori singolari della Decomposizione ai Valori Singolari di un array che sono maggiori di una certa soglia con linalg.matrix_rank di NumPy.

Non preoccuparti se il rango di matrice non ha ancora senso; Lo vedrai meglio più avanti in questo tutorial.

Per ora, concentriamoci su altre due routine che puoi usare:

  • La norma di una matrice si può calcolare con linalg.norm: una norma di matrice è un numero definito in termini delle voci della matrice. La norma è una quantità utile che può dare informazioni importanti su una matrice perché ti dice quanto sono grandi gli elementi.
  • Inoltre, puoi anche calcolare il determinante, un valore utile che può essere calcolato dagli elementi di una matrice quadrata, con linalg.det(). Il determinante riduce una matrice quadrata a un unico numero, che determina se la matrice quadrata è invertibile oppure no.

Infine, risolvere grandi sistemi di equazioni lineari è una delle applicazioni più basilari delle matrici. Se hai un sistema \(Ax = b\), dove \(A\) è una matrice quadrata e \(b\) una matrice generica, hai due metodi che puoi usare per trovare \(x\), a seconda ovviamente del tipo di matrice con cui stai lavorando:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5mcm9tIHNjaXB5IGltcG9ydCBsaW5hbGdcbkEgPSBucC5tYXRyaXgobnAucmFuZG9tLnJhbmRvbSgoMiwyKSkpXG5hID0gbnAuYXJyYXkoWzEsMiwzXSlcbkUgPSBucC5tYXQoYSkuVFxuYiA9IG5wLmFycmF5KFsoMSs1aiwyaiwzaiksICg0aiw1aiw2aildKVxuRiA9IG5wLmV5ZSgzLCBrPTEpIiwic2FtcGxlIjoiIyBEZW5zZSBtYXRyaXggc29sdmVyXG5saW5hbGcuc29sdmUoQSwgYilcblxuIyBMaW5lYXIgbGVhc3Qtc3F1YXJlIHNvbHZlclxubGluYWxnLmxzdHNxKEYsRSkifQ==

Per risolvere matrici sparse, puoi usare linalg.spsolve(). Quando non puoi risolvere l’equazione, potrebbe comunque essere possibile ottenere una \(x\) approssimata con l’aiuto del comando linalg.lstsq().

Consiglio: non perdere il cheat sheet di SciPy di DataCamp.

Ora che hai capito come creare matrici e come usarle per operazioni matematiche, è il momento di affrontare argomenti più avanzati di cui avrai bisogno per addentrarti davvero nel machine learning.

Autovalori e autovettori

Il primo argomento che affronterai sono gli autovalori e gli autovettori.

Gli autovalori sono un nuovo modo per guardare nel cuore di una matrice. Ma prima di approfondire, spieghiamo cosa sono gli autovettori. Quasi tutti i vettori cambiano direzione quando vengono moltiplicati per una matrice. Tuttavia, alcuni vettori eccezionali risultano nella stessa direzione dei vettori ottenuti dalla moltiplicazione. Questi sono gli autovettori.

In altre parole, moltiplica un autovettore per una matrice e il vettore risultante da quella moltiplicazione è uguale a una moltiplicazione dell’autovettore originale con \(\lambda\), l’autovalore: \[Ax = \lambda x. \]

Ciò significa che l’autovalore ti dà informazioni molto preziose: ti dice se uno degli autovettori viene allungato, compresso, invertito o lasciato invariato quando viene moltiplicato per una matrice.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5pbXBvcnQgc2NpcHlcbmZyb20gc2NpcHkgaW1wb3J0IGxpbmFsZyBcbm15TWF0cml4ID0gbnAubWF0cml4KG5wLnJhbmRvbS5yYW5kb20oKDIsMikpKSIsInNhbXBsZSI6IiMgU29sdmUgZWlnZW52YWx1ZSBwcm9ibGVtXG5sYSwgdiA9IGxpbmFsZy5laWcobXlNYXRyaXgpIFxuXG4jIFVucGFjayBlaWdlbnZhbHVlc1xubDEsIGwyID0gbGFcblxuIyBGaXJzdCBlaWdlbnZlY3Rvclxudls6LDBdXG5cbiMgU2Vjb25kIGVpZ2VudmVjdG9yXG52WzosMV1cblxuIyBPciB1bnBhY2sgZWlnZW52YWx1ZXMgd2l0aCBgZWlndmFscygpYFxubGluYWxnLmVpZ3ZhbHMobXlNYXRyaXgpIn0=

Usi la funzione eig() del modulo SciPy linalg per risolvere problemi di autovalori ordinari o generalizzati per matrici quadrate.

Nota che la funzione eigvals() è un altro modo per estrarre gli autovalori di una matrice.

Quando lavori con matrici sparse, puoi fare affidamento sul modulo scipy.sparse per fornirti le funzioni corrette per trovare autovalori e autovettori:

la, v = sparse.linalg.eigs(myMatrix,1)

Nota che il codice sopra specifica il numero di autovalori e autovettori da recuperare, cioè 1.

Autovalori e autovettori sono concetti importanti in molte tecniche di computer vision e machine learning, come la Principal Component Analysis (PCA) per la riduzione della dimensionalità e EigenFaces per il riconoscimento facciale.

Decomposizione ai valori singolari (SVD)

Successivamente, devi conoscere la SVD se vuoi davvero imparare la data science. La decomposizione ai valori singolari di una matrice \(A\) è la decomposizione o fattorizzazione di \(A\) nel prodotto di tre matrici: \(A = U * \Sigma * V^t\).

La dimensione delle singole matrici è la seguente se sai che la matrice \(A\) è di dimensione \(M\) x \(N\):

  • La matrice \(U\) è di dimensione \(M\) x \(M\)
  • La matrice \(V\) è di dimensione \(N\) x \(N\)
  • La matrice \(\Sigma\) è di dimensione \(M\) x \(N\)

Il simbolo \(*\) indica che le matrici sono moltiplicate e il \(^t\) che vedi in \(V^t\) significa che la matrice è trasposta, cioè righe e colonne sono scambiate.

Detto semplicemente, la decomposizione ai valori singolari fornisce un modo per scomporre una matrice in parti più semplici e significative. Queste parti possono contenere alcuni dati che ci interessano.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5mcm9tIHNjaXB5IGltcG9ydCBsaW5hbGdcbmIgPSBucC5hcnJheShbKDErNWosMmosM2opLCAoNGosNWosNmopXSlcbm15TWF0cml4ID0gbnAuYXNtYXRyaXgoYikiLCJzYW1wbGUiOiIjIFNpbmd1bGFyIFZhbHVlIERlY29tcG9zaXRpb25cblUscyxWaCA9IGxpbmFsZy5zdmQobXlNYXRyaXgpIFxuXG4jIEluaXRpYWxpemUgYE1gIGFuZCBgTmBcbk0sTiA9IG15TWF0cml4LnNoYXBlXG5cbiMgQ29uc3RydWN0IHNpZ21hIG1hdHJpeCBpbiBTVkRcblNpZyA9IGxpbmFsZy5kaWFnc3ZkKHMsTSxOKSJ9

Nota che per le matrici sparse puoi usare la funzione sparse.linalg.svds() per eseguire la decomposizione.

Se sei nuovo alla data science, la decomposizione in matrici potrebbe sembrarti piuttosto opaca: potresti non vedere subito casi d’uso in cui applicarla. Ma la SVD è utile in molti compiti, come compressione dei dati, riduzione del rumore e analisi dei dati. Di seguito vedrai come la SVD può essere usata per comprimere immagini:

# Import the necessary packagesimport numpy as npfrom scipy import linalgfrom skimage import dataimport matplotlib.pyplot as plt# Get an image from `skimage`img= data.camera()# Check number of singular valueslinalg.svdvals(img)# Singular Value DecompositionU, s, Vh = linalg.svd(img)# Use only 32 singular valuesA = np.dot(U[:,0:32],           np.dot(np.diag(s[0:32]), Vh[0:32,:]))fig = plt.figure(figsize=(8, 3))# Add a subplot to the figureax = fig.add_subplot(121)# Plot `img` on grayscaleax.imshow(img, cmap='gray')# Add a second subplot to the figureax2 = fig.add_subplot(122)# Plot `A` in the second subplotax2.imshow(A)# Add a titlefig.suptitle('Image Compression with SVD', fontsize=14, fontweight='bold')# Show the plotplt.show()

Che ti darà il seguente risultato:


image compression with svd

Considera anche i seguenti esempi in cui viene usata la SVD:

  • La SVD è strettamente collegata alla Principal Component Analysis (PCA), che viene usata per la riduzione della dimensionalità: entrambe producono un set di “nuovi assi” costruiti da combinazioni lineari degli assi dello spazio delle feature dei tuoi dati. Questi “nuovi assi” scompongono la varianza nei punti dati in base al contributo di ciascuna direzione alla varianza nei dati. Per vedere un esempio concreto di come funziona la PCA sui dati, vai al nostro tutorial su Scikit-Learn.
  • Un altro collegamento è con il data mining e l’elaborazione del linguaggio naturale (NLP): il Latent Semantic Indexing (LSI). È una tecnica usata nel recupero di documenti e nella similarità tra parole. Il latent semantic indexing usa la SVD per raggruppare i documenti in concetti che possono consistere di diverse parole presenti in quei documenti. Varie parole possono essere raggruppate in un concetto. Anche qui, la SVD riduce la correlazione rumorosa tra parole e documenti e diminuisce il numero di dimensioni che i dati originali hanno.

Vedi, la SVD è un concetto importante nel tuo percorso di data science che devi coprire. Ecco perché dovresti considerare di approfondire la SVD oltre quanto coperto da questo tutorial: ad esempio, vai a questa pagina per leggere di più su questa decomposizione di matrici.

Cosa c’è dopo?

Sei arrivato alla fine del tutorial! Da qui in poi, la strada dipende completamente da te.

Ma aspetta!

Non perderti i corsi che vanno più a fondo nell’algebra lineare: questo tutorial è stata solo un’introduzione all’argomento e non ha coperto tutto!

Ovviamente, considera anche di seguire il tutorial sul Machine Learning di DataCamp, che aggiungerà sicuramente valore al tuo percorso di apprendimento dopo questo tutorial su Scipy sull’algebra lineare. Ma, se vuoi tornare alle basi, passa attraverso il nostro tutorial su NumPy o il corso Intermediate Python for Data Science.

Argomenti
Python
Data Science
Analisi dei dati

Scopri di più su Python

Corso

Python - Livello Intermedio

4 ore
1.4M
Migliora le tue competenze nella scienza dei dati creando visualizzazioni con Matplotlib e manipolando DataFrames con pandas.
Vedi i dettagliRight Arrow
Inizia Il Corso
Mostra altroRight Arrow
Correlato

blog

Tokenizzazione nel NLP: come funziona, sfide e casi d'uso

Guida al preprocessing NLP nel machine learning. Copriamo spaCy, i transformer di Hugging Face e come funziona la tokenizzazione in casi d'uso reali.
Abid Ali Awan's photo

Abid Ali Awan

10 min

blog

Che cos'è Snowflake? Guida per principianti alla piattaforma dati cloud

Esplora le basi di Snowflake, la piattaforma dati cloud. Scopri la sua architettura, le sue funzionalità e come integrarla nelle tue pipeline di dati.
Tim Lu's photo

Tim Lu

12 min

blog

I 15 migliori server MCP remoti che ogni AI builder dovrebbe conoscere nel 2026

Scopri i 15 migliori server MCP remoti che stanno trasformando lo sviluppo AI nel 2026. Scopri come migliorano automazione, ragionamento, sicurezza e velocità dei workflow.
Abid Ali Awan's photo

Abid Ali Awan

15 min

Mostra AltroMostra Altro