Gestione degli array con NumPy: indexing e slicing di vettori

In questo breve post proverò a esporre alcuni concetti base relativi la gestione degli array con NumPy.

selezione array con numpy
fonte: O’Reilly

Cosa è NumPy

NumPy è un pacchetto per il calcolo scientifico con Python.

Aggiunge sostanzialmente la possibilità di gestire vettori e matrici multidimensionali con funzioni matematiche.

Il pacchetto è stato rilasciato per la prima volta nel 2005 da Travis Oliphant (che è anche il fondatore di Anaconda).

NumPy è open source e rappresenta un vero coltellino svizzero a disposizione di tutti i data scientist.

Installiamo e importiamo Numpy

NumPy è spesso preinstallato su molti sistemi con già a bordo Python.

Se ti occorre installarlo utilizzando il package manager PyPI:

pip3 install scipy

(se sei sotto Linux… mai lanciare pip con permessi di super user!)

SciPy è una libreria open source di strumenti scientifici di cui NumPy fa parte.

Una volta installata la libreria non ci resta che provarla.

Lanciamo il nostro notebook Jupyter, o più semplicemente l’interprete Python, e scriviamo:

import numpy as np

Da ora nel nostro codice abbrevieremo il nome della libreria come np.

Gestione degli array con NumPy

Adesso però andiamo al sodo.

Creiamo innanzitutto un array.

Iniziamo con un vettore monodimensionale, composto da tre elementi:

In [1]: x = np.array([1, 2, 3])

Se chiedo al sistema in cosa consiste la variabile x, non ci sono dubbi:

In [2]: x
Out[2]: array([1, 2, 3])

In [3]: type(x)
Out[3]: numpy.ndarray

Si tratta di un oggetto della classe numpy, metodo array, vettore per l’appunto.

I vettori possono essere concatenati tra loro utilizzando il metodo append.

In [4]: y = np.array([4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
In [5]: z = np.append(x, y)
In [6]: z
Out[6]: array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])

Selezione, indexing e slicing di un array

Ora proviamo ad accedere al contenuto del semplice array appena creato.

L’indexing del vettore viene eseguito alla maniera classica degli informatici:
il primo elemento è la posizione 0, il secondo posizione 1, il terzo 2 e così via.
Come nel C++, per intenderci.

Quindi se voglio sapere qual è il terzo elemento del mio vettore:

In [7]: z[3]
Out[7]: 4

In realtà le possibilità di selezione e porzionamento (slicing) sono ben più ampie.

The basic slice syntax is i:j:k where i is the starting index, j is the stopping index, and k is the step.

dalla documentazione ufficiale di SciPy

Pertanto la sintassi di base per la selezione degli elementi presenti nel vettore è la seguente:

vettore[i:j:k]

dove

  • i è l’indice di partenza, il primo elemento che verrà selezionato (incluso)
  • j è l’indice di stop, l’elemento sul quale si interromperà la selezione (escluso)
  • k è l’eventuale salto da eseguire nella selezione degli elementi

Non resta che provare qualche selezione sul vettore z di cui sopra:

In [8]: z[3:7]
Out[8]: array([4, 5, 6, 7])
In [9]: z[0:16:3]
Out[9]: array([ 1, 4, 7, 10, 13])
In [10]: z[4:-2]
Out[10]: array([ 5, 6, 7, 8, 9, 10, 11, 12, 13])

(gli indici indicato con segno negativo fanno partire il conteggio all’indietro, dall’ultimo elemento del vettore)

Tutto chiaro.

Aumentiamo ora la complessità del vettore per capire come operare su array multidimensionali.

In [11]: q = z.reshape(5, 3)

In [12]: q
Out[12]:
array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12],
[13, 14, 15]])
In [13]: np.shape(q)
Out[13]: (5, 3)

Ora abbiamo un vettore, q, di dimensione 5 x 3.

Supponiamo di voler selezionare i quattro valori dell’area in basso a destro dell’array.

selezione array numpy

C’è da utilizzare la stessa sintassi, come fatto per l’array a unica dimensione z.

Serve solo qualche dettaglio in più, dato che gli elementi che compongono l’array sono disposti su più dimensioni.

In [14]: z[3:, 1:]
Out[14]:
array([[11, 12],
[14, 15]])

Se ancora non ti è chiaro guarda l’array q come una tabella, come fosse un foglio Excel.
Abbiamo chiesto al PC di selezionare gli elementi dalla quarta riga in poi (3:, inzia la selezione sulla quarta riga, senza limiti, fino alla fine), e dalla secondo colonna in poi (1:, inizia la selezione sulla seconda colonna, fino alla fine).

L’esempio appena fatto è scritto in questo modo perché posso risparmiarmi di scrivere il limite di selezione se questo corrisponde con l’inizio o la fine dell’elemento nell’array.

Per intenderci:

In [15]: z[0:1]
Out[15]: array([[1, 2, 3]])

corrisponde alla forma “contratta”

In [16]: z[:1]
Out[16]: array([[1, 2, 3]])

Prima di chiudere questo articolo proviamo un’ultima selezione:

In [17]: z[::2, 1:]
Out[17]:
array([[ 2, 3],
[ 8, 9],
[14, 15]]

Abbiamo chiesto la selezione di tutte le righe, dall’inizio alla fine, ma in modo alterno (salto 2).
Da questa selezione abbiamo quindi preso i valori delle colonne dalla seconda in poi.

Link di approfondimento

  1. https://www.oreilly.com/library/view/python-for-data/9781449323592/ch04.html
    NumPy Basics: Arrays and Vectorized Computation – from Python for Data Analysis by Wes McKinney
  2. https://jakevdp.github.io/PythonDataScienceHandbook/02.02-the-basics-of-numpy-arrays.html
    An excerpt from the Python Data Science Handbook by Jake VanderPlas
  3. https://www.tutorialspoint.com/numpy/numpy_array_attributes.htm
    NumPy – Array Attributes on Tutorialspoint.com
Summary
Gestione degli array con NumPy: indexing e slicing di vettori
Article Name
Gestione degli array con NumPy: indexing e slicing di vettori
Description
Un'introduzione di base all'indexing e slicing di array in Python, utilizzando la libreria NumPy.
Author
Pubblicato in Data Science, Python.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *