테마
데이터 변환과 병합
학습 목표
- melt로 컬럼 데이터를 행으로 변환(녹이기)할 수 있다
- pivot과 pivot_table의 차이를 이해하고 활용할 수 있다
- groupby로 그룹화된 연산을 수행할 수 있다
- concat으로 서로 다른 DataFrame을 합칠 수 있다
- Tidy Data의 개념을 이해하고 데이터를 정제할 수 있다
전체 구조
1. Tidy Data 개념
Tidy Data는 분석에 적합한 데이터 형태를 말한다. Hadley Wickham이 제안한 원칙으로, 다음 조건을 만족하는 데이터이다.
2. melt - 컬럼을 행으로 녹이기
기간 데이터가 컬럼으로 펼쳐진 데이터를 행으로 변환한다.
python
import pandas as pd
# 원본: 지역 | 2013년12월 | 2014년1월 | ... (피벗 형태)
df_first = pd.read_csv("data/전국_평균_분양가격_2013_2015.csv",
encoding="cp949")
# melt로 녹이기
df_first_melt = df_first.melt(
id_vars=["지역"], # 고정할 컬럼 (id)
var_name="기간", # 녹인 컬럼명 → 새 컬럼 이름
value_name="평당분양가격" # 녹인 값 → 새 컬럼 이름
)
print(df_first_melt.head())
# 지역 기간 평당분양가격
# 서울 2013년12월 ...
# 부산 2013년12월 ...3. 기간 데이터 분리 - apply와 사용자 함수
melt 후 "2013년12월" 같은 기간 문자열에서 연도와 월을 분리해야 한다.
python
# 연도 추출 함수
def parse_year(date_str):
year = date_str.split("년")[0]
return int(year)
# 월 추출 함수
def parse_month(date_str):
month = date_str.split("년")[-1].replace("월", "")
return int(month)
# apply로 함수 적용
df_first_melt["연도"] = df_first_melt["기간"].apply(parse_year)
df_first_melt["월"] = df_first_melt["기간"].apply(parse_month)4. concat - 두 DataFrame 합치기
컬럼 구조가 같은 두 DataFrame을 수직으로 이어 붙인다.
python
# 공통 컬럼만 선택
cols = ["지역명", "연도", "월", "평당분양가격"]
df_last_prepare = df_last.loc[
df_last["전용면적"] == "전체", cols
].copy()
df_first_prepare = df_first_melt[cols].copy()
# 두 데이터 합치기
df = pd.concat([df_first_prepare, df_last_prepare])
print(df.shape)
# (1224, 4)copy()를 쓰는 이유: 원본 DataFrame의 슬라이스를 변경하면 원본도 영향받을 수 있다.
copy()로 명시적 복사를 하면 원본 데이터를 안전하게 보존한다.
5. groupby - 그룹화된 연산
python
# 지역별 평당분양가격 평균
df.groupby("지역명")["평당분양가격"].mean()
# 전용면적별 평당분양가격 평균
df_last.groupby("전용면적")["평당분양가격"].mean()
# 다중 인덱스 그룹화
df_last.groupby(["연도", "지역명"])["평당분양가격"].mean()
# unstack: 마지막 인덱스를 컬럼으로 변환
df_last.groupby(["연도", "지역명"])["평당분양가격"].mean().unstack()
# 전치(Transpose): 행과 열 교환
df_last.groupby(["연도", "지역명"])["평당분양가격"].mean().unstack().Tgroupby 결과는 Series
6. pivot_table - 명시적 그룹 연산
pivot_table은 groupby와 유사하지만 더 명시적으로 사용할 수 있다.
python
# 지역별 평당분양가격 평균
pd.pivot_table(
df_last,
index="지역명",
values="평당분양가격",
aggfunc="mean" # 기본값이 mean
)
# 연도별 + 지역별 피벗 테이블
pd.pivot_table(
df_last,
index="연도",
columns="지역명", # 컬럼으로 표시
values="평당분양가격"
).round()
# DataFrame에서 직접 호출
df_last.pivot_table(
index="전용면적",
columns="지역명",
values="평당분양가격"
).round()groupby vs pivot_table 비교
| 특성 | groupby | pivot_table |
|---|---|---|
| 반환 타입 | Series | DataFrame |
| 속도 | 빠름 | 약간 느림 |
| 사용법 | 간결 | 명시적 (index, columns, values, aggfunc) |
| 기본 연산 | 없음 (직접 지정) | mean (기본값) |
7. pivot vs pivot_table
python
# pivot: 연산 없이 형태만 변환
df.pivot(index="연도", columns="지역명", values="평당분양가격")
# → 중복값이 있으면 에러 발생
# pivot_table: 연산(aggregation)을 포함
pd.pivot_table(df, index="연도", columns="지역명",
values="평당분양가격", aggfunc="mean")
# → 중복값을 집계 함수로 처리핵심 정리
- melt는 컬럼에 있는 데이터를 행으로 녹여 Tidy Data를 만든다
- apply로 사용자 정의 함수를 Series에 적용하여 전처리한다
- concat으로 같은 구조의 DataFrame을 수직으로 합친다
- groupby는 Series를 반환하여 빠르고, pivot_table은 DataFrame을 반환하여 직관적이다
- pivot은 형태만 변환, pivot_table은 집계 연산도 포함한다
- 서로 다른 형태의 데이터를 합치려면 melt + 전처리 + concat 순서로 작업한다