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

[Pandas] melt

· 수정 · 📖 약 2분 · 688자/단어 #python #pandas #reshape #melt
Pandas melt, DataFrame.melt, pd.melt, wide-to-long

정의

DataFrame.melt()Pandas pivot 의 역방향. wide-format → long-format 변환. 여러 컬럼을 두 컬럼 (variable, value) 으로 합친다.

장기간 시계열 데이터나 시각화 라이브러리 (seaborn, plotly) 입력에 적합하다.

사용 상황

상황적합 여부비고
seaborn / plotly 에 hue 그룹 필요long format 이 표준
tidy data 변환분석 파이프라인 표준
여러 기간 컬럼을 하나로2020, 2021, 2022 컬럼 → year, value
설문 문항별 응답 집계q1, q2, q3question, answer
pivot 의 역방향 복원pivot() 결과 되돌리기
이미 long format 인 데이터불필요

wide vs long 구조

flowchart LR
    WIDE["wide format\n과목별 별도 컬럼"]
    LONG["long format\nsubject + score 컬럼"]
    WIDE -->|"melt()"| LONG
    LONG -->|"pivot()"| WIDE
widenamemathenglishscience
행 수2---
longnamesubjectscore
행 수6--

행 수가 컬럼 수 × 원본 행 수 로 늘어난다.

시각화

기본

python
import pandas as pd
df = pd.DataFrame({
  'name': ['Alice', 'Bob'],
  'math': [90, 80],
  'english': [85, 75],
  'science': [95, 70],
})
melted = df.melt(id_vars='name', var_name='subject', value_name='score')
print(melted)
결과
    name  subject  score
0  Alice     math     90
1    Bob     math     80
2  Alice  english     85
3    Bob  english     75
4  Alice  science     95
5    Bob  science     70

Before (wide):

namemathenglishscience
0Alice908595
1Bob807570

After (long):

namesubjectscore
0Alicemath90
1Bobmath80
2Aliceenglish85
3Bobenglish75
4Alicescience95
5Bobscience70

파라미터

파라미터의미기본값
id_vars유지할 컬럼 (key 역할)-
value_varsmelt 할 컬럼 (생략 시 id_vars 외 모두)모두
var_namemelt 된 컬럼명'variable'
value_name값 컬럼명'value'
ignore_indexTrue 면 새 index, False 면 원본 유지True

일부 컬럼만 melt

df.melt(
    id_vars=['name', 'grade'],
    value_vars=['math', 'english'],   # science 는 제외
    var_name='subject',
    value_name='score',
)

시각화 라이브러리와의 궁합

import seaborn as sns

melted = df.melt(id_vars='name', var_name='subject', value_name='score')
sns.barplot(data=melted, x='subject', y='score', hue='name')
# long format 이라 seaborn 이 자동으로 그룹화

plotly 에서도 동일하게 long format 을 기대한다:

import plotly.express as px

melted = df.melt(id_vars='name', var_name='subject', value_name='score')
fig = px.bar(melted, x='subject', y='score', color='name', barmode='group')
fig.show()

pivot 과의 역관계

import pandas as pd

wide = pd.DataFrame({
    'name': ['Alice', 'Bob'],
    'math': [90, 80],
    'english': [85, 75],
})

# wide → long
long = wide.melt(id_vars='name', var_name='subject', value_name='score')

# long → wide (원래대로)
recovered = long.pivot(index='name', columns='subject', values='score')
recovered.columns.name = None   # 컬럼 이름 제거
recovered = recovered.reset_index()

pd.wide_to_long 대안

컬럼명에 숫자 suffix 가 있을 때 더 간결하다.

# 컬럼: sales_2020, sales_2021, cost_2020, cost_2021
pd.wide_to_long(df, stubnames=['sales', 'cost'], i='company', j='year', sep='_')
# melt 보다 컬럼 분리가 자동화됨

stack 과 비교

# melt 결과: 컬럼화 (subject, score 두 컬럼)
df.melt(id_vars='name', var_name='subject', value_name='score')

# stack 결과: MultiIndex Series
df.set_index('name').stack()
# MultiIndex (name, subject) → value
항목melt()stack()
결과 구조DataFrame (컬럼화)Series (MultiIndex)
id_vars 처리명시적으로 지정index 로 설정 필요
시각화 라이브러리바로 사용 가능reset_index 필요

자주 만나는 패턴

1. 연도별 와이드 데이터 → 시계열 차트

df = pd.DataFrame({
    'company': ['A사', 'B사'],
    '2022': [1000, 800],
    '2023': [1200, 850],
    '2024': [1400, 900],
})
long = df.melt(id_vars='company', var_name='year', value_name='revenue')
# year 컬럼을 int 로 변환
long['year'] = long['year'].astype(int)

2. 설문 응답 데이터

# 컬럼: respondent_id, q1, q2, q3, q4
survey.melt(
    id_vars=['respondent_id', 'age', 'gender'],
    var_name='question',
    value_name='answer'
)

3. A/B 테스트 지표 long format 변환

ab = pd.DataFrame({
    'user_id': ['u1', 'u2'],
    'control_conv': [0.12, 0.15],
    'treatment_conv': [0.14, 0.18],
})
ab_long = ab.melt(
    id_vars='user_id',
    value_vars=['control_conv', 'treatment_conv'],
    var_name='group',
    value_name='conversion_rate'
)

4. groupby 후 집계

# 과목별 평균 점수
melted.groupby('subject')['score'].agg(['mean', 'std', 'count'])

성능

import pandas as pd
import numpy as np

# 1,000 행 × 20 컬럼 melt → 20,000 행
df = pd.DataFrame(
    np.random.randn(1_000, 20),
    columns=[f'col{i}' for i in range(20)]
)
df.insert(0, 'id', range(1_000))

long = df.melt(id_vars='id', var_name='feature', value_name='value')
# 결과: 20,000 행 × 3 컬럼
print(long.shape)   # (20000, 3)
입력 크기melt 시간결과 행 수
1,000 × 10~0.001s10,000
10,000 × 20~0.01s200,000
100,000 × 50~0.5s5,000,000

대용량 데이터에서 melt 후 분석은 메모리 주의. 가능하면 필요한 컬럼만 value_vars 로 지정한다.

WARNING

100,000 행 × 100 컬럼 melt = 10,000,000 행. 메모리 부족이 날 수 있다. value_vars 로 필요한 컬럼만 선택해서 melt 하라.

함정

1. value_vars 안 주면 모든 비-id 컬럼 melt

df.melt(id_vars='name')   # math, english, science, timestamp 모두 melt

원치 않은 컬럼 (예: timestamp, 내부 key) 도 묶일 수 있다.

2. 결과 행 수 폭증

# 1,000 행 × 10 melt 컬럼 = 10,000 행

큰 데이터에서 melt 후 분석은 메모리 주의.

3. var_name 의 default 가 ‘variable’

df.melt(id_vars='name')          # 컬럼명: 'variable', 'value' (불명확)
df.melt(id_vars='name',
        var_name='subject',
        value_name='score')       # 명시적 이름 권장

4. 컬럼 타입 혼합 시 value 컬럼 dtype

# int 컬럼과 str 컬럼이 섞이면 value 가 object 로 업캐스팅
df.melt(id_vars='name')   # value 컬럼이 object dtype

타입이 일관된 컬럼끼리만 melt 하거나, melt 후 타입 변환을 한다.

관련 위키

이 글의 용어 (5개)
[Pandas] agg / aggregatepandas
정의 는 여러 집계 함수를 한 번에 적용 한다. , , 모두에서 사용 가능. 는 같은 함수의 별칭. agg 처리 흐름 사용 상황 | 상황 | 패턴 | |:---|:---| | 전…
[Pandas] groupbypandas
정의 는 데이터를 그룹으로 나누고 (split), 각 그룹에 함수를 적용 (apply), 결과를 합쳐 (combine) 새 DataFrame 으로 만드는 split-apply-c…
[Pandas] pivotpandas
정의 는 long-format → wide-format 변환. 한 열의 고유 값들이 새 컬럼이 되고, 원래 데이터는 그 자리에 배치된다. 집계가 없으므로 같은 (index, co…
[Pandas] pivot_tablepandas
정의 는 의 확장. 집계 함수를 동반 해 중복 (index, columns) 도 처리. Excel 의 피벗 테이블과 가장 가까운 기능. pivottable 처리 흐름 사용 상황 …
[Pandas] stack / unstackpandas
정의 - : 가장 안쪽 컬럼 레벨 -> 행 레벨 (DataFrame -> Series 또는 더 좁은 DataFrame) - : 가장 안쪽 행 레벨 -> 컬럼 레벨 / 의 Mult…

💬 댓글

사이트 검색 / 명령어

검색

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