Selezionare dati da un MultiIndex
Recuperi i dati ai livelli esterno e interno dell'indice usando .loc con tuple, slice e l'helper pd.IndexSlice.
Selezionare dati da un MultiIndex è una lezione Pandas & NumPy Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Pandas & NumPy Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Pandas & NumPy Academy include 4 lezioni in totale.
Navigare nei dati gerarchici
Una volta creato un MultiIndex, servono metodi efficienti per recuperare sottoinsiemi di dati. Pandas offre tre strumenti: .loc con tuple per selezionare etichette esatte, slice() e pd.IndexSlice per selezionare intervalli tra i livelli e .xs() per selezionare una sezione trasversale in corrispondenza di un valore specifico di un livello. Padroneggiare questi schemi di accesso consente di sfruttare appieno la potenza dell'indicizzazione gerarchica.
import pandas as pd
import numpy as np
# Setup: GDP data by country and year
df_flat = pd.DataFrame({
'country': ['USA','USA','USA','UK','UK','UK','DE','DE','DE'],
'year': [2021, 2022, 2023, 2021, 2022, 2023, 2021, 2022, 2023],
'gdp_bn': [23000, 25000, 26000, 3000, 3100, 3200, 4100, 4200, 4350]
})
df = df_flat.set_index(['country', 'year']).sort_index()
print(df)Selezionare in base al livello esterno con .loc
Passi un'unica etichetta del livello esterno a .loc[] per recuperare tutte le righe di quel gruppo. Con un MultiIndex a due livelli (paese, anno), df.loc['USA'] restituisce tutte le righe relative agli Stati Uniti sotto forma di DataFrame, mantenendo solo l'indice interno (anno). Questo comportamento è chiamato rimozione del livello: quando seleziona un valore specifico di un livello esterno, Pandas rimuove quel livello dall'indice dell'oggetto restituito.
import pandas as pd
df_flat = pd.DataFrame({
'country': ['USA','USA','USA','UK','UK','UK'],
'year': [2021, 2022, 2023, 2021, 2022, 2023],
'gdp_bn': [23000, 25000, 26000, 3000, 3100, 3200]
})
df = df_flat.set_index(['country', 'year']).sort_index()
# Select all USA rows
usa = df.loc['USA']
print('All USA rows:')
print(usa)
print('\nRemaining index type:', usa.index.name)Selezionare una tupla specifica con .loc
Per recuperare una singola riga identificata da entrambi i livelli dell'indice, passi una tupla a .loc[]: df.loc[('USA', 2022)]. Viene restituita una Series (o uno scalare per una singola colonna) corrispondente esattamente a quella combinazione di etichette (esterna, interna). Deve inserire la tupla in una lista, df.loc[[('USA', 2022)]], se desidera ottenere un DataFrame anziché una Series.
import pandas as pd
df_flat = pd.DataFrame({
'country': ['USA','USA','USA','UK','UK','UK'],
'year': [2021, 2022, 2023, 2021, 2022, 2023],
'gdp_bn': [23000, 25000, 26000, 3000, 3100, 3200],
'cpi': [3.2, 5.1, 4.8, 2.5, 3.4, 3.0]
})
df = df_flat.set_index(['country', 'year']).sort_index()
# Single row as Series
print('USA 2022 (Series):')
print(df.loc[('USA', 2022)])
# Single row as DataFrame
print('\nUSA 2022 (DataFrame):')
print(df.loc[[('USA', 2022)]])Selezionare più righe con un elenco di tuple
Per selezionare contemporaneamente più righe specifiche, passi un elenco di tuple a .loc[]. È utile quando deve ottenere un sottoinsieme non contiguo di righe identificate da chiavi composite, ad esempio i dati del 2022 per Stati Uniti e Regno Unito, ma non per la Germania. Il risultato mantiene il MultiIndex nel DataFrame restituito.
import pandas as pd
df_flat = pd.DataFrame({
'country': ['USA','USA','UK','UK','DE','DE'],
'year': [2022, 2023, 2022, 2023, 2022, 2023],
'gdp_bn': [25000, 26000, 3100, 3200, 4200, 4350]
})
df = df_flat.set_index(['country', 'year']).sort_index()
# Select specific (country, year) combinations
subset = df.loc[[('USA', 2022), ('UK', 2023), ('DE', 2022)]]
print(subset)Usare lo slicing con pd.IndexSlice
pd.IndexSlice (generalmente indicato con l'alias idx) consente di scrivere slice di intervalli per i livelli di un MultiIndex senza costruire manualmente tuple di slice prolisse. Sintassi: df.loc[idx[outer_slice, inner_slice], column_slice]. Ad esempio, df.loc[idx['UK':'USA', 2022:2023], :] seleziona tutte le righe in cui il livello esterno è compreso tra UK e USA e quello interno tra il 2022 e il 2023. Per funzionare correttamente, l'indice deve essere ordinato.
import pandas as pd
import numpy as np
years = [2021, 2022, 2023]
countries = ['DE', 'UK', 'USA']
mi = pd.MultiIndex.from_product([countries, years], names=['country', 'year'])
df = pd.DataFrame({'gdp': np.random.randint(3000, 26000, 9)}, index=mi)
idx = pd.IndexSlice
# Select UK and USA for years 2022 and 2023
subset = df.loc[idx['UK':'USA', 2022:2023], :]
print(subset)Accedere a una sezione trasversale con .xs()
df.xs(key, level=) seleziona tutte le righe in cui un livello specifico è uguale a un determinato valore, indipendentemente dal contenuto degli altri livelli. A differenza di .loc, che richiede di specificare prima i livelli esterni, .xs può raggiungere direttamente qualsiasi livello tramite il suo nome. Ad esempio, df.xs(2022, level='year') restituisce tutte le righe del 2022 per tutti i paesi senza dover specificare 'USA', 'UK' o 'DE'.
import pandas as pd
import numpy as np
countries = ['DE', 'UK', 'USA']
years = [2021, 2022, 2023]
mi = pd.MultiIndex.from_product([countries, years], names=['country', 'year'])
df = pd.DataFrame({'gdp': [4100,4200,4350, 3000,3100,3200, 23000,25000,26000]}, index=mi)
# All countries for year 2022 (inner level)
print('All data for year 2022:')
print(df.xs(2022, level='year'))
# All years for UK (outer level)
print('\nAll years for UK:')
print(df.xs('UK', level='country'))Accedere alle colonne di un MultiIndex
Quando un DataFrame ha un MultiIndex sulle colonne, usi le tuple per accedere a colonne specifiche: df[('revenue', 'Q1')]. Per selezionare tutte le colonne di un livello esterno, ad esempio tutte le colonne relative ai ricavi, usi df['revenue'], che restituisce un DataFrame con tutte le colonne del livello interno sotto quella chiave esterna. Lo schema pd.IndexSlice funziona anche sui multi-indici delle colonne se combinato con .loc.
import pandas as pd
import numpy as np
metrics = ['revenue', 'cost']
quarters = ['Q1', 'Q2', 'Q3', 'Q4']
cols = pd.MultiIndex.from_product([metrics, quarters], names=['metric', 'quarter'])
df = pd.DataFrame(
np.random.randint(50, 200, (3, 8)),
columns=cols,
index=['USA', 'UK', 'DE']
)
# Access all revenue columns
print('Revenue columns:')
print(df['revenue'])
# Access a specific cell
print('\nUSA revenue Q1:', df.loc['USA', ('revenue', 'Q1')])Selezionare il livello interno per tutte le chiavi esterne
Per selezionare un singolo valore del livello interno per tutti i valori del livello esterno, combini .loc con slice(None) per il livello esterno: df.loc[(slice(None), 2022), :]. In questo modo seleziona la riga del 2022 per ogni paese. La versione con pd.IndexSlice è più leggibile: df.loc[idx[:, 2022], :]. Questo schema è spesso necessario quando desidera ottenere una fotografia di tutte le entità in uno specifico momento.
import pandas as pd
import numpy as np
countries = ['DE', 'UK', 'USA']
years = [2021, 2022, 2023]
mi = pd.MultiIndex.from_product([countries, years], names=['country', 'year'])
df = pd.DataFrame({'gdp': [4100,4200,4350, 3000,3100,3200, 23000,25000,26000]}, index=mi)
idx = pd.IndexSlice
# All countries for year 2022 (using IndexSlice)
all_2022 = df.loc[idx[:, 2022], :]
print('All countries in 2022:')
print(all_2022)Problemi comuni nella selezione con MultiIndex
Tre problemi comuni: 1) Indice non ordinato: lo slicing di un MultiIndex non ordinato genera UnsortedIndexError o restituisce risultati errati: chiami sempre sort_index() prima dello slicing. 2) KeyError con una tupla come chiave: se passa una tupla senza racchiuderla in .loc[], Python la interpreta come indicizzazione posizionale: usi sempre .loc per accedere a un MultiIndex in base alle etichette. 3) Incompatibilità dei livelli: dopo groupby, i nomi dei livelli del MultiIndex potrebbero non corrispondere a quelli attesi: controlli df.index.names prima dello slicing.
import pandas as pd
# Unsorted MultiIndex slicing
tuples = [('B', 2), ('A', 1), ('B', 1), ('A', 2)]
mi = pd.MultiIndex.from_tuples(tuples, names=['letter', 'num'])
df = pd.DataFrame({'value': [10, 20, 30, 40]}, index=mi)
print('Is sorted:', df.index.is_monotonic_increasing)
# Sort before slicing
df = df.sort_index()
print('After sort:', df.index.is_monotonic_increasing)
idx = pd.IndexSlice
print('\nSlice A:')
print(df.loc[idx['A', :], :])Esempio pratico: report trimestrale
Un caso d'uso concreto: ha dati sulle vendite indicizzati per (regione, trimestre) e deve estrarre il quarto trimestre per tutte le regioni per un report di fine anno. Usi .xs('Q4', level='quarter') per ottenere questa sezione trasversale con una sola chiamata. Quindi calcoli il totale con .sum(). Questo schema, ovvero aggregazione con groupby → risultato MultiIndex → estrazione di una sezione trasversale, è estremamente comune nei flussi di reporting aziendale.
import pandas as pd
import numpy as np
regions = ['North', 'South', 'East', 'West']
quarters = ['Q1', 'Q2', 'Q3', 'Q4']
mi = pd.MultiIndex.from_product([regions, quarters], names=['region', 'quarter'])
np.random.seed(42)
df = pd.DataFrame({
'sales': np.random.randint(200, 500, 16),
'units': np.random.randint(50, 150, 16)
}, index=mi)
# Extract Q4 performance across all regions
q4 = df.xs('Q4', level='quarter')
print('Q4 Results by Region:')
print(q4)
print('\nQ4 Total Sales:', q4['sales'].sum())Combinare la selezione di un MultiIndex con le colonne
Può selezionare contemporaneamente righe e colonne specifiche usando .loc[row_indexer, column_list]. Con un MultiIndex, l'indicizzatore delle righe può essere una tupla, un elenco di tuple o IndexSlice, mentre l'indicizzatore delle colonne può essere un nome di colonna o un elenco di nomi. In questo modo può estrarre una precisa sotto-tabella rettangolare da un DataFrame gerarchico con una sola espressione.
import pandas as pd
import numpy as np
countries = ['DE', 'UK', 'USA']
years = [2021, 2022, 2023]
mi = pd.MultiIndex.from_product([countries, years], names=['country', 'year'])
df = pd.DataFrame({
'gdp': [4100,4200,4350, 3000,3100,3200, 23000,25000,26000],
'inflation': [1.5, 2.1, 2.8, 2.0, 3.4, 2.9, 3.2, 5.1, 4.8],
'unemployment': [5.0, 4.8, 4.5, 4.5, 4.2, 4.0, 3.8, 3.5, 3.3]
}, index=mi)
idx = pd.IndexSlice
# UK and USA, years 2022-2023, only gdp and inflation
result = df.loc[idx['UK':'USA', 2022:2023], ['gdp', 'inflation']]
print(result)Verifica rapida
Verifichi la propria comprensione della selezione con MultiIndex illustrata in questa lezione.
Riepilogo della lezione
In questa lezione ha imparato a usare .loc con tuple per selezionare combinazioni specifiche di etichette (esterna, interna), pd.IndexSlice per gli slice di intervallo su qualsiasi livello e .xs() per estrarre una sezione trasversale a qualsiasi livello, indipendentemente dalle chiavi esterne. Ordini sempre prima l'indice per evitare UnsortedIndexError. Ora vedremo l'allineamento degli indici e il reindicizzamento, ovvero come Pandas allinea due DataFrame a un indice comune.
Impara Python con un tutor IA — gratis
Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.
- Corsi
- 30
- Lezioni
- 120
Domande Frequenti
La lezione «Selezionare dati da un MultiIndex» è gratuita?
Sì — il testo completo di «Selezionare dati da un MultiIndex» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Pandas & NumPy Academy, passa a CoddyKit PRO. Il corso Pandas & NumPy Academy include 4 lezioni in totale.
Cosa imparerò in «Selezionare dati da un MultiIndex»?
Recuperi i dati ai livelli esterno e interno dell'indice usando .loc con tuple, slice e l'helper pd.IndexSlice. Eserciti Pandas & NumPy Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Pandas & NumPy Academy?
Non è richiesta alcuna esperienza precedente. Pandas & NumPy Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «Selezionare dati da un MultiIndex»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Pandas & NumPy Academy?
Sì. Ogni lezione Pandas & NumPy Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Creare un MultiIndex
- Selezionare dati da un MultiIndex
- Allineamento e reindicizzazione degli indici
- Vantaggi prestazionali degli indici ordinati