0Pricing
Pandas & NumPy Academy · Lezione

stack e unstack con MultiIndex

Trasformi il livello di colonna più interno nell'indice delle righe con stack() e svolga l'operazione inversa con unstack().

stack e unstack con MultiIndex è una lezione Pandas & NumPy Academy gratuita su CoddyKit. Questa è la lezione 3 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.

Introduzione a stack e unstack

stack() e unstack() sono strumenti di Pandas per modificare la forma dei dati, spostandoli tra l'indice delle righe e l'indice delle colonne. Sono particolarmente utili quando si lavora con DataFrame che hanno un MultiIndex su uno dei due assi. stack() prende il livello più interno dell'indice delle colonne e lo ruota trasformandolo nel livello più interno dell'indice delle righe, mentre unstack() esegue l'operazione inversa.

stack(): dalle colonne alle righe

DataFrame.stack() sposta il livello più interno delle etichette delle colonne nel livello più interno dell'indice delle righe, producendo un risultato più lungo e più stretto. Se il DataFrame originale aveva colonne semplici (non multiple), il risultato è una Series con un MultiIndex. Se le colonne avevano più livelli, stack() riduce di uno il numero dei livelli delle colonne.

import pandas as pd

df = pd.DataFrame({
    'Math': [85, 90, 78],
    'Science': [92, 88, 95]
}, index=['Alice', 'Bob', 'Carol'])

print(df)
#        Math  Science
# Alice    85       92
# Bob      90       88
# Carol    78       95

stacked = df.stack()
print(stacked)
# Alice    Math       85
#          Science    92
# Bob      Math       90
#          Science    88
# Carol    Math       78
#          Science    95
# dtype: int64

unstack(): dalle righe alle colonne

Series.unstack() (o DataFrame.unstack()) è l'inverso di stack(). Prende il livello più interno dell'indice delle righe e lo ruota trasformandolo in nuove etichette delle colonne, producendo un risultato più largo. È funzionalmente simile a pivot(), ma opera direttamente sull'indice anziché sui valori delle colonne.

stacked = df.stack()
print(type(stacked))  # Series with MultiIndex

# Restore the original wide format
df_restored = stacked.unstack()
print(df_restored)
#        Math  Science
# Alice    85       92
# Bob      90       88
# Carol    78       95

# Identical to the original df!

Selezionare il livello da sottoporre a stack

Per i DataFrame con un MultiIndex sulle colonne, stack(level) consente di scegliere quale livello ruotare. Passi un numero di livello (0 per il più esterno, -1 per il più interno, valore predefinito) oppure il nome di un livello. Analogamente, unstack(level) seleziona il livello dell'indice delle righe da ruotare trasformandolo in colonne. Questo controllo dettagliato è essenziale per gestire strutture di dati gerarchiche complesse.

# MultiIndex columns
arrays = [['Math', 'Math', 'Science', 'Science'],
          ['Q1', 'Q2', 'Q1', 'Q2']]
multi_cols = pd.MultiIndex.from_arrays(arrays, names=['subject', 'quarter'])

df_multi = pd.DataFrame([[85, 90, 92, 88], [78, 80, 95, 91]],
                        index=['Alice', 'Bob'], columns=multi_cols)

# Stack the 'quarter' level (innermost, level=-1)
print(df_multi.stack(level='quarter').head())

unstack() su livelli specifici delle righe

Quando il DataFrame ha un MultiIndex sulle righe, situazione comune dopo un groupby() su più colonne, può applicare unstack() a uno specifico livello delle righe per distribuirlo sulle colonne. Questo è un modello molto comune per creare riepiloghi in stile tabella a doppia entrata senza chiamare esplicitamente pivot_table().

# GroupBy produces MultiIndex rows
df2 = pd.DataFrame({
    'region': ['East', 'East', 'West', 'West'],
    'product': ['A', 'B', 'A', 'B'],
    'sales': [100, 150, 120, 200]
})

# MultiIndex result from groupby
multi = df2.groupby(['region', 'product'])['sales'].sum()
print(multi)

# Unstack the product level into columns
wide = multi.unstack('product')
print(wide)
# product    A    B
# region
# East     100  150
# West     120  200

Gestire i valori mancanti in stack/unstack

Quando si chiama unstack() e non esiste ogni combinazione di indice delle righe per ciascun livello delle colonne, Pandas riempie le celle mancanti con NaN. Al contrario, per impostazione predefinita stack() elimina le righe costituite interamente da NaN. Può controllare questo comportamento con il parametro dropna: passi stack(dropna=False) per conservare le righe con NaN.

# Incomplete data: West has no product B
df3 = df2[df2['product'] != 'B'].copy()
multi3 = df3.groupby(['region', 'product'])['sales'].sum()

wide3 = multi3.unstack('product', fill_value=0)
print(wide3)
# product    A    B
# region
# East     100    0  <- B filled with 0 instead of NaN
# West     120    0

stack() e poi calcolare sulle righe

Un modello molto efficace consiste nell'applicare stack() a un DataFrame wide per convertire le colonne in righe, eseguire un'operazione sulle righe, come un filtro o un groupby, e infine applicare unstack() per tornare al formato wide. In questo modo non è necessario scrivere cicli colonna per colonna e il codice rimane vettorializzato e leggibile. È particolarmente utile per applicare simultaneamente la stessa trasformazione a ogni colonna.

# Normalise each column by its column mean using stack/compute/unstack
normalised = (
    df.stack()
      .groupby(level=1)
      .transform(lambda s: (s - s.mean()) / s.std())
      .unstack()
)
print(normalised.round(2))
#        Math  Science
# Alice  0.0     0.39
# Bob    1.13   -1.09
# Carol -1.13    0.71

stack() per la visualizzazione

Come melt(), anche stack() converte i dati in formato long, che è il formato previsto da Seaborn e da molti strumenti ausiliari di Matplotlib. La differenza principale è che stack() opera sull'indice delle colonne e conserva la struttura MultiIndex, mentre melt() produce un DataFrame long con struttura piatta. Entrambi permettono di adottare flussi di lavoro simili per la creazione dei grafici.

# Prepare data for line plot using stack
long = df.stack().reset_index()
long.columns = ['student', 'subject', 'score']
print(long)
#   student  subject  score
# 0   Alice     Math     85
# 1   Alice  Science     92
# ...

# Ready for: sns.barplot(data=long, x='student', y='score', hue='subject')

swaplevel() per riordinare gli indici

Dopo l'applicazione di stack, il livello più interno delle righe corrisponde al nome originale della colonna. A volte si desidera che il livello esterno sia il nome della variabile e quello interno l'indice originale delle righe. Utilizzi swaplevel() sul MultiIndex per scambiare l'ordine di due livelli, quindi sort_index() per ripristinare un ordinamento ordinato.

stacked = df.stack()  # MultiIndex: (student, subject)
swapped = stacked.swaplevel()  # MultiIndex: (subject, student)
swapped = swapped.sort_index()
print(swapped)
# subject  student
# Math     Alice      85
#          Bob        90
#          Carol      78
# Science  Alice      92
#          Bob        88
#          Carol      95

Quando usare stack, melt o pivot

Scelga stack() quando lavora con DataFrame con colonne MultiIndex e desidera ridurre di uno i livelli delle colonne. Scelga melt() quando ha un DataFrame piatto e desidera passare dal formato wide al formato long, controllando quali colonne diventeranno righe. Scelga pivot()/pivot_table() per passare dal formato long al formato wide. Questi tre strumenti coprono tutte le esigenze di modifica della forma wide/long in Pandas.

# Decision guide (comment, not executable standalone):
# MultiIndex columns -> want fewer levels: use stack()
# Flat wide -> need long format for plotting/ML: use melt()
# Long -> need wide summary table: use pivot_table()
# Wide -> back to long: use melt() or stack()

# Example: stack when you have pivot_table output (MultiIndex cols)
tbl = df2.groupby(['region', 'product'])['sales'].sum().unstack()
long_again = tbl.stack().rename('sales').reset_index()
print(long_again)

Riepilogo pratico: scheda di riferimento per la modifica della forma

Ecco un modello mentale sintetico: stack() — le colonne confluiscono nelle righe e il DataFrame diventa più stretto e più alto. unstack() — le righe si espandono nelle colonne e il DataFrame diventa più largo e più corto. melt() — le colonne denominate confluiscono in una coppia chiave-valore (due nuove colonne). pivot_table() — una colonna chiave-valore si espande in più colonne. Tutte e quattro le operazioni sono reversibili; sapere quale direzione scegliere dipende semplicemente dal decidere se l'analisi prevista preferisce il formato wide o long.

# stack/unstack cycle
df_wide = df.copy()             # wide format
df_long = df_wide.stack()       # long via stack
df_wide2 = df_long.unstack()    # back to wide

# melt/pivot cycle
df_melted = df_wide.melt(id_vars=[])    # wide -> long
# df_pivoted = df_melted.pivot(...)     # long -> wide

print('Original shape:  ', df_wide.shape)
print('After stack:     ', df_long.shape)
print('After unstack:   ', df_wide2.shape)

Verifica rapida

Verifichi la Sua comprensione di stack e unstack con MultiIndex, come illustrato in questa lezione.

Riepilogo della lezione

In questa lezione ha imparato che stack() ruota le etichette delle colonne nell'indice delle righe per produrre un risultato più lungo e più stretto; unstack() esegue l'operazione inversa, ruotando un livello dell'indice delle righe trasformandolo in colonne; entrambi funzionano con strutture MultiIndex create da operazioni groupby; infine, swaplevel() consente di riordinare i livelli degli indici. Ora esamineremo pd.crosstab() per creare rapidamente tabelle di frequenza tra colonne categoriali.

Domande Frequenti

La lezione «stack e unstack con MultiIndex» è gratuita?

Sì — il testo completo di «stack e unstack con 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 «stack e unstack con MultiIndex»?

Trasformi il livello di colonna più interno nell'indice delle righe con stack() e svolga l'operazione inversa con unstack(). 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 3 di 4.

Quanto tempo richiede la lezione «stack e unstack con 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

  1. pivot_table: tabulazione incrociata
  2. melt: dal formato ampio al formato lungo
  3. stack e unstack con MultiIndex
  4. crosstab per tabelle di frequenza
← Torna a Pandas & NumPy Academy