본문으로 건너뛰기
김신건의 로그

[Pandas] stack / unstack

· 수정 · 📖 약 1분 · 235자/단어 #python #pandas #reshape #multiindex
Pandas stack, Pandas unstack, Pandas stack-unstack, Pandas stack / unstack, MultiIndex 변환

정의

  • stack() : 가장 안쪽 컬럼 레벨 → 행 레벨 (DataFrame → Series 또는 더 좁은 DataFrame)
  • unstack() : 가장 안쪽 행 레벨 → 컬럼 레벨

Pandas pivot / Pandas melt 의 MultiIndex 기반 버전.

stack 기본

python
import pandas as pd
df = pd.DataFrame(
  {'math': [90, 80], 'english': [85, 75]},
  index=['Alice', 'Bob']
)
print(df)
print('--- stack ---')
print(df.stack())
결과
       math  english
Alice    90       85
Bob      80       75
--- stack ---
Alice  math       90
     english    85
Bob    math       80
     english    75
dtype: int64

DataFrame 의 2 컬럼이 MultiIndex Series 로 합쳐졌다.

unstack 기본

s.unstack()      # 가장 안쪽 index level → columns
s.unstack(level=0)   # 0번 level 을 columns 로
multi = df.stack()    # Series
multi.unstack()       # 원래 DataFrame 으로 복원

다단계 unstack

df = pd.DataFrame({
    'region': ['Seoul', 'Seoul', 'Busan', 'Busan'],
    'product': ['A', 'B', 'A', 'B'],
    'sales': [100, 200, 150, 250],
}).set_index(['region', 'product'])['sales']

df.unstack()                # product 가 컬럼
df.unstack(level='region')  # region 이 컬럼
python
import pandas as pd
s = pd.Series([100, 200, 150, 250],
  index=pd.MultiIndex.from_tuples(
      [('Seoul','A'),('Seoul','B'),('Busan','A'),('Busan','B')],
      names=['region','product']
  ))
print(s.unstack())
결과
product    A    B
region
Busan    150  250
Seoul    100  200
region \ productAB
Busan150250
Seoul100200

pivot / melt 와의 비교

동작DataFrame APIMultiIndex API
long → widepivot, pivot_tableunstack
wide → longmeltstack

대부분의 경우 pivot / melt 가 더 직관적. stack / unstack 은 MultiIndex 가 이미 있는 경우 자연스러움.

groupby + unstack 패턴

df.groupby(['region', 'product'])['sales'].sum().unstack('product')

groupby 가 MultiIndex 결과를 반환 → unstack 으로 wide 형태.

fill_value

s.unstack(fill_value=0)     # NaN 을 0 으로

stack 의 dropna

df.stack(dropna=False)      # NaN 도 결과에 포함 (기본은 제거)

함정

1. stack 한 결과의 타입

  • DataFrame.stack → Series (일반)
  • DataFrame.stack(level=0) → DataFrame (남은 컬럼 레벨이 있으면)

2. unstack 의 level 지정

s.unstack()                 # 가장 안쪽 level (기본)
s.unstack(level=-1)         # 같음
s.unstack(level=0)          # 가장 바깥 level
s.unstack(level='product')  # 이름으로

이름으로 지정이 명확.

3. 데이터가 너무 sparse 하면 NaN 폭증

# 10 region × 1000 product 의 unstack → 10000 셀 대부분 NaN

이런 경우 long-format 유지가 메모리 효율적.

참고

이 글의 용어 (4개)
[Pandas] meltpandas
정의 는 의 역방향. wide-format → long-format 변환. 여러 컬럼을 두 컬럼 ( , ) 으로 합친다. 장기간 시계열 데이터나 시각화 (ggplot, seabo…
[Pandas] MultiIndexpandas
정의 MultiIndex 는 여러 단계 (level) 의 라벨로 구성된 . SQL 의 composite key 와 비슷, 그룹화된 데이터를 자연스럽게 표현. 생성 인덱싱 <Cod…
[Pandas] pivotpandas
정의 는 long-format → wide-format 변환. 한 열의 고유 값들이 새 컬럼이 되고, 원래 데이터는 그 자리에 배치된다. 집계가 없으므로 같은 (index, co…
[Pandas] pivot_tablepandas
정의 는 의 확장. 집계 함수를 동반 해 중복 (index, columns) 도 처리. Excel 의 피벗 테이블과 가장 가까운 기능. 기본 <CodeWithOutput lang…

이 개념을 다룬 위키 페이지 (3)

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기