Skip to content

데이터 변환과 병합


학습 목표

  1. melt로 컬럼 데이터를 행으로 변환(녹이기)할 수 있다
  2. pivot과 pivot_table의 차이를 이해하고 활용할 수 있다
  3. groupby로 그룹화된 연산을 수행할 수 있다
  4. concat으로 서로 다른 DataFrame을 합칠 수 있다
  5. 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().T

groupby 결과는 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 비교

특성groupbypivot_table
반환 타입SeriesDataFrame
속도빠름약간 느림
사용법간결명시적 (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 순서로 작업한다