A mio avviso, la risposta accettata è confusa, poiché utilizza un DataFrame con solo valori mancanti. Anche io non mi piace il termine basato sulla posizione per .iloc
e invece, preferiscono integer posizione in quanto è molto più descrittivo e esattamente ciò che .iloc
rappresenta. La parola chiave è INTEGER - ha .iloc
bisogno di INTEGERS.
Vedi le mie serie di blog estremamente dettagliate sulla selezione dei sottoinsiemi per ulteriori informazioni
.ix è obsoleto e ambiguo e non dovrebbe mai essere usato
Poiché .ix
è deprecato, ci concentreremo solo sulle differenze tra .loc
e .iloc
.
Prima di parlare delle differenze, è importante capire che DataFrames ha etichette che aiutano a identificare ogni colonna e ogni indice. Diamo un'occhiata a un DataFrame di esempio:
df = pd.DataFrame({'age':[30, 2, 12, 4, 32, 33, 69],
'color':['blue', 'green', 'red', 'white', 'gray', 'black', 'red'],
'food':['Steak', 'Lamb', 'Mango', 'Apple', 'Cheese', 'Melon', 'Beans'],
'height':[165, 70, 120, 80, 180, 172, 150],
'score':[4.6, 8.3, 9.0, 3.3, 1.8, 9.5, 2.2],
'state':['NY', 'TX', 'FL', 'AL', 'AK', 'TX', 'TX']
},
index=['Jane', 'Nick', 'Aaron', 'Penelope', 'Dean', 'Christina', 'Cornelia'])
Tutte le parole in grassetto sono le etichette. Le etichette, age
, color
, food
, height
, score
e state
sono utilizzati per le colonne . Gli altri marchi, Jane
, Nick
, Aaron
, Penelope
, Dean
, Christina
, Cornelia
sono utilizzati per l'index .
I modi principali per selezionare determinate righe in un DataFrame sono con gli indicizzatori .loc
e .iloc
. Ognuno di questi indicizzatori può anche essere utilizzato per selezionare contemporaneamente le colonne, ma per ora è più semplice concentrarsi solo sulle righe. Inoltre, ciascuno degli indicizzatori utilizza una serie di parentesi che seguono immediatamente il proprio nome per effettuare le selezioni.
.loc seleziona i dati solo dalle etichette
Parleremo prima .loc
dell'indicizzatore che seleziona i dati solo dalle etichette dell'indice o della colonna. Nel nostro DataFrame di esempio, abbiamo fornito nomi significativi come valori per l'indice. Molti DataFrame non avranno nomi significativi e, invece, saranno predefiniti solo ai numeri interi da 0 a n-1, dove n è la lunghezza del DataFrame.
Esistono tre diversi input per cui è possibile utilizzare .loc
- Una stringa
- Un elenco di stringhe
- Taglia la notazione usando le stringhe come valori di inizio e fine
Selezione di una singola riga con .loc con una stringa
Per selezionare una singola riga di dati, posizionare l'etichetta dell'indice all'interno delle parentesi seguenti .loc
.
df.loc['Penelope']
Ciò restituisce la riga di dati come una serie
age 4
color white
food Apple
height 80
score 3.3
state AL
Name: Penelope, dtype: object
Selezione di più righe con .loc con un elenco di stringhe
df.loc[['Cornelia', 'Jane', 'Dean']]
Ciò restituisce un DataFrame con le righe nell'ordine specificato nell'elenco:
Selezione di più righe con .loc con notazione slice
La notazione delle sezioni è definita da un valore di avvio, arresto e step. Quando si taglia per etichetta, i panda includono il valore di arresto nel ritorno. Le seguenti sezioni da Aaron a Dean, incluso. La dimensione del passo non è definita in modo esplicito, ma per impostazione predefinita è 1.
df.loc['Aaron':'Dean']
Le sezioni complesse possono essere prese allo stesso modo delle liste Python.
.iloc seleziona i dati solo per posizione intera
Passiamo ora a .iloc
. Ogni riga e colonna di dati in un DataFrame ha una posizione intera che lo definisce. Ciò si aggiunge all'etichetta visualizzata visivamente nell'output . La posizione intera è semplicemente il numero di righe / colonne dall'alto / a sinistra a partire da 0.
Esistono tre diversi input per cui è possibile utilizzare .iloc
- Un numero intero
- Un elenco di numeri interi
- Taglia la notazione usando numeri interi come valori di inizio e fine
Selezione di una singola riga con .iloc con un numero intero
df.iloc[4]
Ciò restituisce la quinta riga (posizione intera 4) come una serie
age 32
color gray
food Cheese
height 180
score 1.8
state AK
Name: Dean, dtype: object
Selezione di più righe con .iloc con un elenco di numeri interi
df.iloc[[2, -2]]
Ciò restituisce un DataFrame della terza e seconda all'ultima riga:
Selezione di più righe con .iloc con notazione slice
df.iloc[:5:3]
Selezione simultanea di righe e colonne con .loc e .iloc
Un'ottima capacità di entrambi .loc/.iloc
è la possibilità di selezionare contemporaneamente righe e colonne. Negli esempi sopra, tutte le colonne sono state restituite da ciascuna selezione. Siamo in grado di scegliere colonne con gli stessi tipi di input utilizzati per le righe. Dobbiamo semplicemente separare la selezione di righe e colonne con una virgola .
Ad esempio, possiamo selezionare le righe Jane e Dean con solo l'altezza delle colonne, segnare e dichiarare in questo modo:
df.loc[['Jane', 'Dean'], 'height':]
Questo utilizza un elenco di etichette per le righe e la notazione delle sezioni per le colonne
Naturalmente possiamo fare operazioni simili .iloc
usando solo numeri interi.
df.iloc[[1,4], 2]
Nick Lamb
Dean Cheese
Name: food, dtype: object
Selezione simultanea con etichette e posizione intera
.ix
è stato usato per effettuare selezioni simultaneamente con etichette e posizione di numeri interi che a volte era utile ma confusa e ambigua e per fortuna è stato deprecato. Nel caso in cui sia necessario effettuare una selezione con una combinazione di etichette e posizioni di numeri interi, sarà necessario effettuare sia le etichette di selezione sia le posizioni di numeri interi.
Ad esempio, se vogliamo selezionare le righe Nick
e Cornelia
insieme alle colonne 2 e 4, potremmo utilizzare .loc
convertendo i numeri interi in etichette con quanto segue:
col_names = df.columns[[2, 4]]
df.loc[['Nick', 'Cornelia'], col_names]
In alternativa, converti le etichette degli indici in numeri interi con il get_loc
metodo index.
labels = ['Nick', 'Cornelia']
index_ints = [df.index.get_loc(label) for label in labels]
df.iloc[index_ints, [2, 4]]
Selezione booleana
L'indicizzatore .loc può anche fare una selezione booleana. Ad esempio, se siamo interessati a trovare tutte le righe in cui l'età è superiore a 30 e restituiamo solo le colonne food
e score
, possiamo fare quanto segue:
df.loc[df['age'] > 30, ['food', 'score']]
Puoi replicarlo con .iloc
ma non puoi passargli una serie booleana. È necessario convertire la serie booleana in un array intorpidito come questo:
df.iloc[(df['age'] > 30).values, [2, 4]]
Selezione di tutte le righe
È possibile utilizzare .loc/.iloc
solo per la selezione delle colonne. Puoi selezionare tutte le righe usando i due punti come questo:
df.loc[:, 'color':'score':2]
L'operatore di indicizzazione []
, può selezionare anche righe e colonne ma non contemporaneamente.
Molte persone hanno familiarità con lo scopo principale dell'operatore di indicizzazione DataFrame, ovvero selezionare le colonne. Una stringa seleziona una singola colonna come Serie e un elenco di stringhe seleziona più colonne come DataFrame.
df['food']
Jane Steak
Nick Lamb
Aaron Mango
Penelope Apple
Dean Cheese
Christina Melon
Cornelia Beans
Name: food, dtype: object
L'uso di un elenco consente di selezionare più colonne
df[['food', 'score']]
Ciò che le persone hanno meno familiarità è che, quando viene utilizzata la notazione delle sezioni, la selezione avviene per etichette di riga o per posizione di numero intero. Questo è molto confuso e qualcosa che non uso quasi mai, ma funziona.
df['Penelope':'Christina'] # slice rows by label
df[2:6:2] # slice rows by integer location
La spiegazione di .loc/.iloc
per selezionare le righe è altamente preferita. Il solo operatore di indicizzazione non è in grado di selezionare contemporaneamente righe e colonne.
df[3:5, 'color']
TypeError: unhashable type: 'slice'