stack i unstack z MultiIndex
Przenoś najbardziej wewnętrzny poziom kolumn do indeksu wierszy za pomocą stack() i odwracaj tę operację za pomocą unstack().
stack i unstack z MultiIndex to bezpłatna lekcja Pandas & NumPy Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Pandas & NumPy Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Pandas & NumPy Academy zawiera 4 lekcji w sumie.
Wprowadzenie do stack i unstack
Funkcje stack() i unstack() to narzędzia Pandas do zmiany kształtu danych, które przenoszą dane między indeksem wierszy a indeksem kolumn. Są szczególnie przydatne podczas pracy z obiektami DataFrame, które mają MultiIndex na jednej z osi. Funkcja stack() przenosi najbardziej wewnętrzny poziom indeksu kolumn do najbardziej wewnętrznego poziomu indeksu wierszy, natomiast unstack() wykonuje operację odwrotną.
stack(): kolumny na wiersze
DataFrame.stack() przenosi najbardziej wewnętrzny poziom etykiet kolumn do najbardziej wewnętrznego poziomu indeksu wierszy, tworząc dłuższy i węższy wynik. Jeśli pierwotny DataFrame miał proste kolumny (bez MultiIndex), wynikiem jest Series z MultiIndex. Jeśli kolumny miały wiele poziomów, funkcja stack() zmniejsza ich liczbę o jeden.
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: int64unstack(): wiersze na kolumny
Series.unstack() (lub DataFrame.unstack()) jest odwrotnością funkcji stack(). Pobiera najbardziej wewnętrzny poziom indeksu wierszy i przenosi go do nowych etykiet kolumn, tworząc szerszy wynik. Funkcjonalnie przypomina to funkcję pivot(), ale operuje bezpośrednio na indeksie, a nie na wartościach kolumn.
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!Wybieranie poziomu do operacji stack
W przypadku obiektów DataFrame z MultiIndex na kolumnach funkcja stack(level) pozwala wybrać poziom, który ma zostać przeniesiony. Należy przekazać numer poziomu (0 oznacza poziom najbardziej zewnętrzny, -1 najbardziej wewnętrzny i jest wartością domyślną) albo nazwę poziomu. Analogicznie funkcja unstack(level) wybiera poziom indeksu wierszy, który ma zostać przeniesiony do kolumn. Tak precyzyjna kontrola jest niezbędna podczas pracy ze złożonymi hierarchicznymi strukturami danych.
# 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() na określonych poziomach wierszy
Gdy DataFrame ma MultiIndex wierszy (co często ma miejsce po użyciu funkcji groupby() dla wielu kolumn), można zastosować unstack() do określonego poziomu wierszy, aby rozłożyć go na kolumny. Jest to bardzo częsty wzorzec służący do tworzenia podsumowań w stylu tabel przestawnych bez jawnego wywoływania funkcji 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 200Obsługa brakujących wartości w stack/unstack
Gdy wywołana zostanie funkcja unstack(), a nie każda kombinacja indeksu wierszy występuje dla każdego poziomu kolumn, Pandas wstawia w brakujące komórki wartość NaN. Z kolei funkcja stack() domyślnie usuwa wiersze, które w całości zawierają NaN. Można to kontrolować za pomocą parametru dropna: należy przekazać stack(dropna=False), aby zachować wiersze z wartościami 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 0stack(), a następnie obliczenia na wierszach
Skuteczny wzorzec polega na użyciu funkcji stack() do przekształcenia szerokiego DataFrame tak, aby kolumny stały się wierszami, wykonaniu operacji wierszowej, takiej jak filtrowanie lub groupby, a następnie użyciu unstack() w celu powrotu do formatu szerokiego. Eliminuje to konieczność pisania pętli przetwarzających kolumny pojedynczo, a kod pozostaje zwektoryzowany i czytelny. Jest to szczególnie przydatne, gdy tę samą transformację należy zastosować jednocześnie do każdej kolumny.
# 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.71stack() do tworzenia wykresów
Podobnie jak melt(), funkcja stack() przekształca dane do formatu długiego, którego oczekują biblioteka Seaborn i wiele funkcji pomocniczych Matplotlib. Główna różnica polega na tym, że stack() działa na indeksie kolumn i zachowuje strukturę MultiIndex, natomiast melt() tworzy płaski DataFrame w formacie długim. Obie funkcje prowadzą do podobnego sposobu tworzenia wykresów.
# 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() do zmiany kolejności indeksów
Po użyciu funkcji stack najbardziej wewnętrzny poziom wierszy odpowiada pierwotnej nazwie kolumny. Czasami pożądane jest, aby poziom zewnętrzny zawierał nazwę zmiennej, a poziom wewnętrzny — pierwotny indeks wierszy. Należy użyć funkcji swaplevel() na MultiIndex, aby zamienić kolejność dwóch poziomów, a następnie funkcji sort_index(), aby przywrócić uporządkowaną kolejność.
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 95Kiedy używać stack, melt i pivot
Funkcji stack() należy używać podczas pracy z obiektami DataFrame z kolumnami MultiIndex, gdy chcą Państwo zmniejszyć liczbę poziomów kolumn o jeden. Funkcji melt() należy używać w przypadku płaskiego DataFrame, gdy chcą Państwo przejść z formatu szerokiego do długiego i kontrolować, które kolumny staną się wierszami. Funkcje pivot()/pivot_table() służą do przejścia z formatu długiego z powrotem do szerokiego. Te trzy narzędzia obejmują wszystkie potrzeby związane ze zmianą kształtu danych szerokich i długich w 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)Praktyczne podsumowanie: ściąga dotycząca zmiany kształtu danych
Oto zwięzły model mentalny: stack() — kolumny są składane do wierszy, a DataFrame staje się węższy i wyższy. unstack() — wiersze są rozwijane do kolumn, a DataFrame staje się szerszy i niższy. melt() — nazwane kolumny są składane do pary klucz–wartość (dwóch nowych kolumn). pivot_table() — kolumna klucza–wartości jest rozwijana do wielu kolumn. Wszystkie cztery operacje są odwracalne, a wybór kierunku sprowadza się do ustalenia, czy docelowa analiza lepiej działa na danych w formacie szerokim, czy długim.
# 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)Szybkie sprawdzenie
Sprawdź swoją wiedzę na temat funkcji stack i unstack oraz MultiIndex z tej lekcji.
Podsumowanie lekcji
W tej lekcji nauczyli się Państwo, że funkcja stack() przenosi etykiety kolumn do indeksu wierszy, tworząc dłuższy i węższy wynik; unstack() wykonuje operację odwrotną, przenosząc poziom indeksu wierszy do kolumn; obie funkcje działają ze strukturami MultiIndex tworzonymi przez operacje groupby; a swaplevel() umożliwia zmianę kolejności poziomów indeksu. Następnie poznają Państwo funkcję pd.crosstab() do szybkiego tworzenia tabel częstości dla kolumn kategorycznych.
Często zadawane pytania
Czy lekcja „stack i unstack z MultiIndex” jest bezpłatna?
Tak — pełny tekst „stack i unstack z MultiIndex” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Pandas & NumPy Academy, przejdź na CoddyKit PRO. Kurs Pandas & NumPy Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „stack i unstack z MultiIndex”?
Przenoś najbardziej wewnętrzny poziom kolumn do indeksu wierszy za pomocą stack() i odwracaj tę operację za pomocą unstack(). Ćwiczysz Pandas & NumPy Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Pandas & NumPy Academy?
Nie wymagamy żadnego doświadczenia. Pandas & NumPy Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „stack i unstack z MultiIndex”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Pandas & NumPy Academy?
Tak. Każda lekcja Pandas & NumPy Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- pivot_table: tabulacja krzyżowa
- melt: format szeroki na długi
- stack i unstack z MultiIndex
- crosstab do tabel częstości