Pandas MultiIndex: 계층 인덱싱 완전 정복 가이드
Updated on
MultiIndex는 panel 데이터, 시계열, 피벗·리셰이프된 데이터에 대해 깔끔한 계층 구조를 제공하지만, 슬라이싱이 불안정하게 느껴지고 level 순서가 헷갈린다는 이유로 많은 사용자가 사용을 꺼립니다.
- 문제: (region + year, symbol + field 같은) 중첩 차원을 일반 컬럼이나 wide 테이블에 그대로 두면 점점 지저분해집니다.
- 긴장: 임시방편으로 reshape를 반복하다 보면 중복된 컬럼명, 정렬 깨짐, 다중 키 선택 시 에러가 자주 발생합니다.
- 해결: 소수의 반복 가능한 패턴을 사용하세요.
set_index로 MultiIndex를 만들고,.loc/.xs로 안전하게 슬라이스하며,swaplevel/reorder_levels로 level을 재배열하고,stack/unstack으로 형태를 변환합니다.
Want an AI agent that understands your pandas notebooks and MultiIndex slicing?
RunCell is a JupyterLab AI agent that can read your code, analyze DataFrames, understand notebook context, debug errors, and even generate & execute code for you. It works directly inside JupyterLab—no switching windows or copy-pasting.
👉 Try RunCell: runcell.dev (opens in a new tab)
빠른 참고(Quick Reference)
| 작업 | 메서드 | 코드 스니펫 |
|---|---|---|
| 컬럼에서 계층 인덱스 생성 | set_index | df.set_index(["region", "year"]).sort_index() |
| Cartesian product로 생성 | pd.MultiIndex.from_product | pd.MultiIndex.from_product([regions, years], names=["region", "year"]) |
| 특정 level 기준 슬라이스 | .loc 또는 .xs | df.loc[("EMEA", 2024)] 또는 df.xs("EMEA", level="region") |
| level 순서 재배치 | swaplevel, reorder_levels | df.swaplevel("region", "year") |
| level 삭제 또는 평탄화 | droplevel, reset_index | df.droplevel("year"), df.reset_index() |
| wide/long 변환 | unstack / stack | df.unstack("field"), df.stack("field") |
예제 데이터
import pandas as pd
records = [
("EMEA", 2023, "revenue", 120),
("EMEA", 2023, "profit", 25),
("EMEA", 2024, "revenue", 140),
("NA", 2024, "revenue", 210),
("NA", 2024, "profit", 50),
]
df = (
pd.DataFrame(records, columns=["region", "year", "metric", "value"])
.set_index(["region", "year", "metric"])
.sort_index()
)MultiIndex 구조 만들기
기존 컬럼에서 생성하기
sales = raw_df.set_index(["region", "year"]).sort_index()- 여러 level을 걸친 슬라이싱을 예측 가능하게 하려면
sort_index()를 사용하세요. - 금액처럼 일반 컬럼으로 남겨두고 싶은 값은 index로 보내지 않고 컬럼에 유지하세요.
product 또는 튜플에서 생성하기
idx = pd.MultiIndex.from_product(
[["EMEA", "NA"], [2023, 2024]],
names=["region", "year"],
)
frame = pd.DataFrame(index=idx, columns=["revenue"]).sort_index()from_product는 모든 조합이 존재하도록 보장합니다. 이미 (region, year) 쌍이 리스트로 준비돼 있다면 from_tuples를 사용하세요.
MultiIndex로 선택하기
# 계층을 따라 한 경로를 지정
emea_2024 = df.loc[("EMEA", 2024)]
# 특정 level에 대한 단면(cross section), 나머지 level은 유지
emea = df.xs("EMEA", level="region")
# 슬라이스를 이용한 부분 선택 (정렬된 인덱스 필요)
idx = pd.IndexSlice
subset = df.loc[idx[:, 2024, :], :].xs(cross-section)는 나머지 level 구조를 유지한 채 특정 level만 잘라낼 때 유용합니다.- 시계열 계층에서는 index를 정렬한 뒤
IndexSlice로 범위를 지정하면 가독성이 좋아집니다.
level 재배치 및 정리
# year를 region 앞에 가져오기
reordered = df.swaplevel("region", "year").sort_index(level=["year", "region"])
# 3개 이상의 level을 명시적으로 재배열
df_reordered = df.reorder_levels(["metric", "region", "year"])
# 더 이상 필요 없는 level은 제거
flat = df.droplevel("metric")swaplevel은 인접한 두 level을 빠르게 교환할 때,reorder_levels는 임의의 순서로 재배열할 때 사용합니다.- 재배열 후에는
sort_index(level=...)를 호출해 부분 슬라이싱에 필요한 단조(monotonic) 정렬을 복원하세요.
Stack / Unstack으로 리셰이프하기
index level을 축으로 삼아 wide ↔ long 형태를 자유롭게 변환할 수 있습니다.
wide = df.unstack("metric") # metric 값이 컬럼으로 이동
long_again = wide.stack("metric")- 존재하지 않는 조합에 값을 채우려면
unstack에서fill_value=를 사용하세요. - 컬럼 기준으로 pivot 스타일 변환을 할 때는 수동 루프 대신
set_index([...]).unstack()과stack()조합을 활용하는 것이 좋습니다.
MultiIndex vs 일반 컬럼, 언제 무엇을 쓸까?
| 상황 | MultiIndex 사용 | 일반 컬럼 사용 |
|---|---|---|
| 계층적 라벨이 슬라이싱의 중심 (region → year → metric) | ✅ .loc/.xs로 자연스럽게 처리 | ⚠️ 반복 필터링/조인이 필요 |
| 보고용 wide 레이아웃 | ✅ 필요할 때 unstack으로 컬럼화 | ⚠️ 컬럼명 중복 위험 |
| 키 컬럼으로 자주 merge | ⚠️ 먼저 reset 후 merge | ✅ 키를 컬럼으로 둔 채 join |
| CSV/Parquet로 내보내기 | ✅ 쓰기 전에 reset_index() | ✅ 별도 단계 불필요 |
실무 기준: 외부 시스템과 주고받는 저장 형태에서는 키를 명확한 컬럼으로 유지하고, 내부 분석 워크플로에서 계층 슬라이싱·리셰이프가 핵심이면 MultiIndex를 적극 활용하는 것이 좋습니다.
자주 발생하는 함정과 해결책
- 정렬되지 않은 인덱스로 인한 슬라이싱 실패: 부분 슬라이스 전에
sort_index(level=[...])를 호출하세요. - 이름 없는 level: 슬라이싱과
reset_index동작을 명확히 하려면index.names(또는set_index의names=)를 설정하세요. - 읽기 어려운 출력:
df.index.to_frame()으로 각 level을 컬럼처럼 확인할 수 있고, 필요할 때reset_index()로 평탄한 컬럼 구조로 되돌릴 수 있습니다.
MultiIndex를 만드는, 슬라이스하는, 재정렬하는, 리셰이프하는 방식을 패턴으로 표준화하면, 계층 구조의 장점을 혼란 없이 누릴 수 있습니다. 이 패턴들을 pandas-pivot-melt 같은 reshaping 가이드, pandas-resample 같은 시계열 도우미와 함께 사용하면, 다차원 데이터를 처음부터 끝까지 일관되게 관리할 수 있습니다.