Iloc vs Loc in Pandas: Una Guida Con Esempi

Una delle cose fastidiose che tutti stiamo cercando di capire quando impariamo Pandas è la distinzione tra .loc e .iloc.

Mettiamo fine a questa confusione e chiarire la differenza tra questi due metodi. Darò molti esempi e spero che la distinzione sarà molto più chiara alla fine di questo articolo.

Cos’è .loc e .iloc in Pandas?

Sia .loc che .iloc sono attributi essenziali dei DataFrame di Pandas e entrambi vengono utilizzati per selezionare sottoinsiemi specifici di dati. Il loro scopo è accedere e consentire la manipolazione di una parte specifica del DataFrame anziché dell’intero DataFrame. 

Caratteristica

.loc

.iloc

Sintassi

df.loc[indice_righe, indice_colonne]

df.iloc[indice_righe, indice_colonne]

Metodo di indicizzazione

Indicizzazione basata su etichette

Indicizzazione basata sulla posizione

Usato per il riferimento

Etichette (nomi) delle righe e delle colonne

Indici numerici delle righe e delle colonne (a partire da 0)

Come possiamo vedere dalla tabella, la sintassi appare molto simile. La differenza risiede nell’uso degli argomenti row_indexer e column_indexer. Questo perché i due metodi offrono approcci diversi all’indicizzazione dei dati: mentre .loc indicizza in base ai nomi delle etichette, .iloc utilizza gli indici di posizione numerica delle righe e delle colonne come argomenti.

Esaminiamo ora nel dettaglio ciascuno dei due metodi, iniziando da .loc.

Usando .loc: Selezione per etichette

Per illustrare i concetti, consideriamo un ipotetico database clienti rappresentato da questo DataFrame chiamato df, con il ID Cliente che rappresenta l’indice di riga:

ID Cliente

Nome

Paese

Regione

Età

C123

John Doe

Stati Uniti

America del Nord

67

C234

Petra Müller

Germania

Europa

51

C345

Ali Khan

Pakistan

Asia

19

C456

Maria Gonzalez

Mexico

North America

26

C567

David Lee

China

Asia

40

There sono quattro modi principali per selezionare righe con .loc. Questi includono:

  • Selezione di una singola riga
  • Selezione di righe multiple
  • Selezione di un insieme di righe
  • Selezione condizionale delle righe

Selezione di una singola riga usando .loc

Per selezionare una singola riga, utilizziamo l’etichetta della riga che vogliamo recuperare come row_indexer. Di conseguenza, la sintassi appare così: df.loc['etichetta_riga']. Utilizziamo questo metodo per visualizzare tutte le informazioni sul nostro cliente Ali Khan:

df.loc['C345']

C345

 

Nome

Ali Khan

Paese

Pakistan

Regione

Asia

Età

19

Selezionare più righe utilizzando .loc

Se vogliamo selezionare più righe che non seguono necessariamente un ordine, dobbiamo passare un elenco delle loro etichette di riga come argomento row_indexer. Questo significa che dobbiamo utilizzare non uno ma due coppie di parentesi quadre: una per la sintassi regolare di .loc e una per l’elenco delle etichette.

La riga df.loc[['row_label_1', 'row_label_2']] restituirà le due righe del DataFrame df specificate nell’elenco. Diciamo che volessimo conoscere non solo le informazioni su Ali Khan ma anche su David Lee:

df.loc[['C345', 'C567']]

ID Cliente

Nome

Paese

Regione

Età

C345

Ali Khan

Pakistan

Asia

19

C567

David Lee

Cina

Asia

40

Selezione di un intervallo di righe utilizzando .loc

Possiamo selezionare un intervallo di righe passando le etichette della prima e dell’ultima riga con due punti in mezzo: df.loc['etichetta_riga_iniziale':'etichetta_riga_finale']. Possiamo visualizzare le prime quattro righe del nostro DataFrame in questo modo:

df.loc['C123' : 'C456']

ID Cliente

Nome

Paese

Regione

Data di Registrazione

C123

John Doe

Stati Uniti

America del Nord

67

C234

Petra Müller

Germania

Europa

51

C345

Ali Khan

Pakistan

Asia

19

C456

Maria Gonzalez

Messico

America del Nord

26

Ci sono due cose da tenere a mente qui:

  1. L’output include la riga specificata in row_label_end. Questo è diverso in .iloc, che tratteremo più avanti.
  2. Utilizziamo solo una coppia di parentesi quadre, anche se vogliamo recuperare più righe. Non utilizziamo una lista per specificare le varie righe, quindi utilizzare due parentesi quadre restituirebbe un SyntaxError.

Selezione condizionale delle righe usando .loc

Possiamo anche restituire righe basate su un’espressione condizionale. Possiamo filtrare tutte le righe in base al fatto che soddisfino o meno una certa condizione e visualizzare solo quelle che lo fanno.

La sintassi corrispondente è df.loc[conditional_expression], con la conditional_expression che è un’affermazione sui valori consentiti in una colonna specifica.

Per colonne con dati non numerici (come Name o Country), l’istruzione può utilizzare solo l’operatore uguale o disuguale, poiché non c’è un ordine tra i valori. Potremmo, ad esempio, restituire tutte le righe dei clienti che non sono dell’Asia:

df.loc[df['Region'] != 'Asia']

ID Cliente

Nome

Paese

Regione

Età

C123

John Doe

Stati Uniti

Nord America

67

C234

Petra Müller

Germania

Europa

51

C456

Maria Gonzalez

Messico

Nord America

26

La selezione di una singola colonna utilizzando .loc

Per selezionare colonne, dobbiamo specificare l’argomento column_indexer, che viene dopo l’argomento row_indexer. Se vogliamo specificare solo il column_indexer, dobbiamo in qualche modo indicare che vogliamo restituire tutte le righe e filtrare solo sulle colonne. Vediamo come possiamo farlo!

La selezione di una singola colonna può essere fatta specificando il column_indexer con l’etichetta della rispettiva colonna. Per recuperare tutte le righe, dobbiamo specificare il row_indexer con un semplice due punti. Arriviamo a una sintassi che appare così: df.loc[:, 'nome_colonna'].

Mostriamo il Nome di ciascun cliente:

df.loc[:, 'Name']

ID Cliente

Nome

C123

John Doe

C234

Petra Müller

C345

Ali Khan

C456

Maria Gonzalez

C567

David Lee

Selezione di più colonne usando .loc

Simile alla selezione di più righe, dobbiamo passare un elenco di etichette di colonne se vogliamo restituire più colonne di un DataFrame che non seguono necessariamente l’ordine: df.loc[:, [col_label_1, 'col_label_2']].

Supponendo che volessimo aggiungere l’età di tutti i clienti al nostro ultimo output, funzionerebbe così:

df.loc[:, ['Name', 'Age']]

ID cliente

Nome

Età

C123

John Doe

67

C234

Petra Müller

51

C345

Ali Khan

19

C456

Maria Gonzalez

26

C567

David Lee

40

Selezione di una serie di colonne utilizzando .loc

Utilizzare i due punti tra le etichette di due colonne selezionerà tutte le colonne nell’intervallo di ordine tra le due colonne specificate. È inclusiva della colonna finale, il che significa che anche la colonna chiamata col_end sarà selezionata nella sintassi standard, che è la seguente: df.loc[:, 'col_start':'col_end'].

Se fossimo interessati al Nome, Paese e Regione dei nostri clienti, la nostra riga di codice potrebbe essere:

df.loc[:, 'Name':'Region']

ID Cliente

Nome

Paese

Regione

C123

John Doe

Stati Uniti

America del Nord

C234

Petra Müller

Germania

Europa

C345

Ali Khan

Pakistan

Asia

C456

Maria Gonzalez

Messico

America del Nord

C567

David Lee

Cina

Asia

Selezione combinata di righe e colonne utilizzando .loc

È anche possibile specificare sia il row_indexer che il column_indexer. Questo potrebbe essere utilizzato per recuperare un singolo pezzo di informazione, ovvero una cella del DataFrame. Per fare ciò, specifichiamo una riga e una colonna utilizzando la sintassi df.loc['row_label', 'column_name'] .

Il caso più utile è restituire un sub-DataFrame che si concentra esattamente sul set di righe e colonne di nostro interesse. È possibile specificare entrambi gli indexer come liste utilizzando le parentesi quadre, o come uno slice utilizzando i due punti, e persino combinarlo con un’espressione condizionale per la selezione delle righe.

Ecco un esempio di restituzione del Name, Country e Region di ciascun cliente con un Age superiore a 30:

df.loc[df['Age'] > 30, 'Name':'Region']

ID Cliente

Nome

Paese

Regione

C123

John Doe

Stati Uniti

Nord America

C234

Petra Müller

Germany

Europe

C567

David Lee

China

Asia

Utilizzando .iloc: Selezione per posizione intera

.iloc seleziona per posizione anziché per etichetta. Questa è la sintassi standard per utilizzare .iloc: df.iloc[indice_riga, indice_colonna]. Ci sono due cose speciali da tenere d’occhio:

  • Conteggio a partire da 0: La prima riga e colonna hanno l’indice 0, la seconda indice 1, ecc.
  • Esclusività del valore di fine dell’intervallo: Quando si utilizza una fetta, la riga o colonna specificata dopo i due punti non è inclusa nella selezione.

Selezione di una singola riga utilizzando .iloc

Una singola riga può essere selezionata utilizzando l’intero che rappresenta il numero di indice della riga come indice_riga. Non abbiamo bisogno di virgolette poiché stiamo inserendo un numero intero e non una stringa di etichetta come abbiamo fatto con .loc. Per restituire la prima riga di un DataFrame chiamato df, inserire df.iloc[0].

Nel nostro esempio di DataFrame, questa riga di codice restituisce le informazioni di John Doe:

df.iloc[0]

C123

 

Name

John Doe

Country

Stati Uniti

Regione

North America

Età

67

Selezionare più righe utilizzando .iloc

Selezionare più righe funziona in .iloc come in .loc—inseriamo gli indici di riga come interi in una lista con parentesi quadre. La sintassi è simile a questa: df.iloc[[0, 3, 4]].

L’output rispettivo nella nostra tabella dei clienti può essere visto di seguito:

df.iloc[[0, 3, 4]]

ID Cliente

Nome

Paese

Regione

Età

C123

John Doe

Stati Uniti

America del Nord

67

C456

Maria Gonzalez

Messico

America del Nord

26

C567

David Lee

Cina

Asia

40

Selezionare una fetta di righe utilizzando .iloc

Per selezionare una fetta di righe, utilizziamo i due interi di indice di riga specificati. Ora, dobbiamo prestare attenzione all’esclusività menzionata in precedenza. 

Possiamo prendere la riga df.iloc[1:4] come esempio per illustrare questo concetto. Il numero di indice 1 significa la seconda riga, quindi la nostra fetta inizia da lì. L’intero di indice 4 rappresenta la quinta riga, ma poiché .iloc non è inclusivo per la selezione della fetta, il nostro output includerà tutte le righe fino all’ultima prima di questa. Pertanto, restituirà la seconda, terza e quarta riga. 

Dimostriamo che la riga funziona come dovrebbe:

df.iloc[1:4]

ID cliente

Nome

Paese

Regione

Età

C234

Petra Müller

Germania

Europa

51

C345

Ali Khan

Pakistan

Asia

19

C456

Maria Gonzalez

Messico

America del Nord

26

Selezione di una singola colonna utilizzando .iloc

La logica di selezione delle colonne usando .iloc segue quanto appreso finora. Vediamo come funziona per singole colonne, colonne multiple e fette di colonne.

Come con .loc, è importante specificare il row_indexer prima di procedere al column_indexer. Per recuperare i valori della terza colonna di df per ogni riga, inseriamo df.iloc[:, 2].

Poiché Region è la terza colonna nel nostro DataFrame, verrà recuperata come conseguenza di quella riga di codice:

df.iloc[:, 2]

ID Cliente

Regione

C123

America del Nord

C234

Europa

C345

Asia

C456

America del Nord

C567

Asia

Selezionare più colonne utilizzando .iloc

Per selezionare più colonne che non sono necessariamente successive, possiamo inserire nuovamente una lista contenente interi come column_indexer. La riga df.iloc[:, [0, 3]] restituisce sia la prima che la quarta colonna. 

Nel nostro caso, le informazioni visualizzate sono il Nome e l’Età di ciascun cliente:

df.iloc[:, [0, 3]]

ID Cliente

Nome

Età

C123

John Doe

67

C234

Petra Müller

51

C345

Ali Khan

19

C456

Maria Gonzalez

26

C567

David Lee

40

Selezione di una porzione di colonne utilizzando .iloc

Per la selezione delle colonne utilizzando .iloc, la logica del column_indexer segue quella del row_indexer. La colonna rappresentata dall’intero dopo i due punti non è inclusa nell’output. Per recuperare la seconda e la terza colonna, il codice dovrebbe essere simile a questo: df.iloc[:, 1:3].

Questa riga qui sotto restituisce tutte le informazioni geografiche che abbiamo sui nostri clienti:

df.iloc[:, 1:3]

ID Cliente

Paese

Regione

C123

Stati Uniti

Nord America

C234

Germania

Europa

C345

Pakistan

Asia

C456

Messico

Nord America

C567

Cina

Asia

Selezione combinata di righe e colonne utilizzando .iloc

Possiamo mettere insieme ciò che abbiamo imparato su .iloc per combinare la selezione di righe e colonne. Ancora una volta, è possibile restituire una singola cella o un sotto-DataFrame. Per restituire la cella singola all’intersezione della riga 3 e della colonna 4, inseriamo df.iloc[2, 3].

Proprio come con .loc, possiamo specificare entrambi gli indexer come liste utilizzando le parentesi quadre, o come una fetta utilizzando i due punti. Se vogliamo selezionare righe utilizzando espressioni condizionali, tecnicamente è possibile anche con .iloc, ma non è consigliato. Utilizzare i nomi delle etichette e .loc è di solito molto più intuitivo e meno soggetto a errori.

Questo ultimo esempio mostra Paese, Regione e Età per la prima, seconda e quinta riga del nostro DataFrame:

df.iloc[[0,1,4], 1:4]

ID Cliente

Paese

Regione

Età

C123

Stati Uniti

America del Nord

67

C234

Germania

Europa

51

C567

Cina

Asia

40

.iloc vs .loc: Quando usare quale

Generalmente, c’è una regola semplice da seguire in base alla quale la scelta del metodo dipende dalla tua conoscenza del DataFrame:

  • Usa .loc quando conosci le etichette (nomi) delle righe/colonne.
  • Usa .iloc quando conosci le posizioni intere delle righe/colonne.

Alcuni scenari favoriscono l’uso di .loc o .iloc per loro natura. Ad esempio, iterare sulle righe o sulle colonne è più semplice e intuitivo utilizzando numeri interi anziché etichette. Come abbiamo già menzionato, filtrare le righe basandosi su condizioni sui valori delle colonne è meno soggetto a errori utilizzando i nomi delle colonne.

Scenari che favoriscono .loc

Scenari che favoriscono .iloc

Il tuo DataFrame ha nomi significativi per indice/colonne.

Stai iterando sulle righe/colonne in base alla loro posizione.

Devi filtrare in base alle condizioni sui valori delle colonne.

I nomi degli indici/colonne non sono rilevanti per il tuo compito.

KeyError, NameError e Index Error Con .loc e .iloc

Diamo un’occhiata ai possibili problemi. Un errore comune nell’uso di .loc è l’incontro di un KeyError. Questo errore si verifica quando cerchiamo di accedere a un’etichetta di riga o colonna che non esiste nel nostro DataFrame. Per evitarlo, dobbiamo sempre assicurarci che le etichette che stiamo usando siano corrette e corrispondano alle etichette esistenti nel nostro DataFrame e controllare due volte alla ricerca di errori di battitura.

Inoltre, è importante usare sempre le virgolette per le etichette specificate con .loc. Dimenticarle restituirà un NameError.

Un IndexError può verificarsi quando si utilizza .iloc se specifichiamo una posizione intera che è al di fuori dell’intervallo valido degli indici del nostro DataFrame. Ciò accade quando l’indice che si sta cercando di accedere non esiste, sia perché si trova oltre il numero di righe o colonne nel DataFrame o perché è un valore negativo. Per prevenire questo errore, controlla le dimensioni del tuo DataFrame e utilizza valori di indice appropriati all’interno dell’intervallo valido.

Conclusion

Spero che questo blog sia stato utile e che la distinzione tra .loc e .iloc sia ora chiara. Per saperne di più, ecco alcuni buoni passi successivi:

Source:
https://www.datacamp.com/tutorial/loc-vs-iloc