반응형
Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
Tags
- Apache
- Java
- PANDAS
- google apps script
- Excel
- Tkinter
- PySpark
- gas
- math
- PostgreSQL
- GIT
- hive
- string
- dataframe
- matplotlib
- Mac
- Python
- 파이썬
- Kotlin
- Redshift
- Google Excel
- array
- SQL
- django
- Google Spreadsheet
- Github
- list
- numpy
- c#
Archives
- Today
- Total
달나라 노트
Python Pandas : stack, unstack (pivot하기, pivot 풀기) 본문
Python/Python numpy
Python Pandas : stack, unstack (pivot하기, pivot 풀기)
CosmosProject 2026. 5. 20. 21:39728x90
반응형
Pandas stack() / unstack() — 데이터를 넓은 형태와 긴 형태로 변환하는 메서드
열을 행으로 접거나(stack), 행 인덱스를 열로 펼치는(unstack) 메서드입니다. MultiIndex 데이터를 다룰 때 핵심이 되는 한 쌍의 역함수입니다.
핵심 개념 — 넓은 형태 vs 긴 형태
데이터는 넓은 형태(wide)와 긴 형태(long) 두 가지로 표현할 수 있습니다.
넓은 형태 (wide) 긴 형태 (long)
───────────────── ──────────────────────
분기 Q1 Q2 지역 분기 매출
지역 부산 Q1 80
부산 80 120 ←→ 부산 Q2 120
서울 100 150 서울 Q1 100
서울 Q2 150
unstack() ←
→ stack()
stack() |
unstack() |
|
|---|---|---|
| 방향 | 열 → 행 인덱스 | 행 인덱스 → 열 |
| 결과 형태 | 긴 형태 (long) | 넓은 형태 (wide) |
| 반환 타입 | MultiIndex Series | DataFrame |
| 주 사용처 | 분석/집계용 변환 | 피벗 테이블, 시각화 준비 |
기본 문법
DataFrame.stack(level=-1) # 가장 안쪽 열 레벨을 행으로
DataFrame.unstack(level=-1, fill_value=None) # 가장 안쪽 행 레벨을 열로
stack() — 열을 행으로 접기
import pandas as pd
wide = pd.DataFrame({
'Q1': [80, 100],
'Q2': [120, 150]
}, index=['부산', '서울'])
print(wide)
# Q1 Q2
# 부산 80 120
# 서울 100 150
long = wide.stack()
print(long)
# 부산 Q1 80
# Q2 120
# 서울 Q1 100
# Q2 150
# dtype: int64
열(Q1, Q2)이 행 인덱스의 안쪽 레벨로 내려와 MultiIndex Series가 됩니다.
unstack() — 행을 열로 펼치기
stack()의 결과를 다시 원래대로 되돌립니다.
wide_again = long.unstack()
print(wide_again)
# Q1 Q2
# 부산 80 120
# 서울 100 150
level 파라미터 — 어떤 레벨을 올릴지 선택
MultiIndex가 여러 레벨일 때 어떤 레벨을 열로 올릴지 지정합니다. groupby로 집계한 결과가 대표적인 예입니다.
# groupby로 만든 MultiIndex Series
grouped = df.groupby(['지역', '분기'])['매출'].sum()
# 지역 분기
# 부산 Q1 80
# Q2 120
# 서울 Q1 100
# Q2 150
grouped.unstack() # level=-1 (기본): 분기 → 열
# 분기 Q1 Q2
# 지역
# 부산 80 120
# 서울 100 150
grouped.unstack(level=0) # level=0: 지역 → 열
# 지역 부산 서울
# 분기
# Q1 80 100
# Q2 120 150
fill_value — 빈 자리 채우기
데이터에 없는 조합이 생기면 기본적으로 NaN이 채워집니다.
# 부산 Q2 데이터가 없는 경우
grouped.unstack()
# 분기 Q1 Q2
# 지역
# 부산 80.0 NaN ← 빈 자리
# 서울 100.0 150.0
grouped.unstack(fill_value=0)
# 분기 Q1 Q2
# 지역
# 부산 80 0
# 서울 100 150
응용 사례 1 — 월별 카테고리 매출 피벗
sales = pd.DataFrame({
'월': [1, 1, 2, 2, 3, 3],
'카테고리': ['식품', '전자', '식품', '전자', '식품', '전자'],
'매출': [200, 500, 180, 620, 220, 480]
})
# groupby 집계 → unstack으로 피벗
pivot = sales.groupby(['월', '카테고리'])['매출'].sum().unstack(fill_value=0)
# 카테고리 식품 전자
# 월
# 1 200 500
# 2 180 620
# 3 220 480
# 다시 긴 형태로 되돌리고 싶을 때
pivot.stack().reset_index()
# 월 카테고리 매출
# 0 1 식품 200
# 1 1 전자 500
# ...
피벗 형태는 .plot()으로 바로 시각화가 가능합니다.
응용 사례 2 — 교차 분석 및 비율 계산
survey = pd.DataFrame({
'성별': ['남', '남', '여', '여', '남', '여'],
'만족도': ['만족', '불만', '만족', '만족', '만족', '불만'],
})
# 성별 × 만족도 카운트
count = survey.groupby(['성별', '만족도']).size().unstack(fill_value=0)
# 만족도 만족 불만
# 성별
# 남 2 1
# 여 2 1
# 행별 비율 계산
ratio = count.div(count.sum(axis=1), axis=0).round(2)
# 만족도 만족 불만
# 성별
# 남 0.67 0.33
# 여 0.67 0.33
stack() / unstack() 역함수 관계
original = pivot # 넓은 형태
stacked = pivot.stack() # 긴 형태로 접기
restored = stacked.unstack() # 다시 넓은 형태로 복원
# original == restored (완전히 동일)
핵심 직관:
stack은 표를 세로로 접고, unstack은 가로로 펼칩니다. 둘은 완전한 역함수 관계라 df.stack().unstack()은 원본과 동일합니다.728x90
반응형
'Python > Python numpy' 카테고리의 다른 글
| Python numpy : nan_to_num (0) | 2026.05.20 |
|---|---|
| Python numpy : sum, mean (0) | 2026.05.20 |
| Python numpy : minimum() / maximum() — 두 array를 element-wise로 비교해 작은/큰 값을 선택하는 메서드 (0) | 2026.05.14 |
| Python numpy : where() — 조건에 따라 두 값 중 하나를 선택하는 메서드 (0) | 2026.05.14 |
| Python numpy : polyfit() — 점들의 패턴에 가장 잘 맞는 다항식 계수를 추정하는 메서드 (0) | 2026.05.14 |
Comments
