"두 개의 DataFrame을 합치고 싶다면?"
엑셀의 VLOOKUP처럼 Pandas에서도 데이터를 합칠 수 있습니다!
목차
1. 왜 필요할까?
2. merge() vs join() 핵심 차이
3. merge()
4. join()
5. 조인 타입 4가지
6. 실전 팁
1. 왜 필요할까?
실생활 예시
온라인 쇼핑몰 데이터:
[회원 정보] [주문 정보]
회원ID | 이름 주문ID | 회원ID | 상품
1001 | 김민수 O001 | 1001 | 노트북
1002 | 이영희 O002 | 1002 | 마우스
1003 | 박철수 O003 | 1001 | 키보드
"김민수가 뭘 샀는지 알고 싶다면?" → 회원ID를 기준으로 두 테이블을 합쳐야 합니다!
2. merge() vs join() 핵심 차이
구분 | merge() | join() |
기본 기준 | 컬럼 | 인덱스 |
사용법 | pd.merge(df1, df2) | df1.join(df2) |
간결성 | 보통 | 짧음 |
유연성 | 높음 | 보통 |
언제? | 대부분의 경우 ✅ | 인덱스 조인만 |
결론: 처음엔 merge()만 써도 충분합니다!
3. merge() 완전 정복
1) 기본: 컬럼으로 합치기
import pandas as pd
# 회원 정보
members = pd.DataFrame({
'user_id': [101, 102, 103],
'name': ['김민지', '이하늘', '박서준']
})
# 주문 정보
orders = pd.DataFrame({
'user_id': [101, 102, 101],
'product': ['노트북', '마우스', '키보드']
})
# user_id 기준으로 합치기
result = pd.merge(members, orders, on='user_id')
print(result)
출력:
user_id name product
0 101 김민지 노트북
1 101 김민지 키보드
2 102 이하늘 마우스
그림으로 이해하기:
members orders
┌───────┬──────┐ ┌───────┬────────┐
│user_id│ name │ │user_id│ product│
├───────┼──────┤ ├───────┼────────┤
│ 101 │ 김민지 │ → │ 101 │ 노트북 │
│ 102 │ 이하늘 │ + │ 102 │ 마우스 │
│ 103 │ 박서준 │ │ 101 │ 키보드 │
└───────┴──────┘ └───────┴────────┘
↓
merge(on='user_id')
↓
┌───────┬──────┬───────┐
│user_id│ name │product│
├───────┼──────┼───────┤
│ 101 │ 김민지 │ 노트북 │
│ 101 │ 김민지 │ 키보드 │
│ 102 │ 이하늘 │ 마우스 │
└───────┴──────┴───────┘
(박서준은 주문이 없어서 제외)
2) 컬럼명이 다를 때
students = pd.DataFrame({
'student_id': [201, 202, 203],
'name': ['철수', '영희', '민수']
})
grades = pd.DataFrame({
'id': [201, 202, 203], # 컬럼명이 다름!
'score': [85, 92, 78]
})
# left_on, right_on 사용
result = pd.merge(students, grades,
left_on='student_id', right_on='id')
print(result)
출력:
student_id name id score
0 201 철수 201 85
1 202 영희 202 92
2 203 민수 203 78
3) 인덱스로 합치기
# 인덱스가 있는 데이터
employees = pd.DataFrame({
'name': ['김대리', '이과장', '박부장'],
'dept': ['개발', '기획', '영업']
}, index=[1001, 1002, 1003])
salaries = pd.DataFrame({
'salary': [5000, 6000, 7000]
}, index=[1001, 1002, 1003])
# 인덱스 기준 합치기
result = pd.merge(employees, salaries,
left_index=True, right_index=True)
print(result)
출력:
name dept salary
1001 김대리 개발 5000
1002 이과장 기획 6000
1003 박부장 영업 7000
그림으로 이해:
employees (인덱스=사번) salaries (인덱스=사번)
┌────┬────┬────┐ ┌────┬──────┐
│ │name│dept│ │ │salary│
├────┼────┼────┤ ├────┼──────┤
│1001│김대리│ 개발│ + │1001│ 5000 │
│1002│이과장│ 기획│ │1002│ 6000 │
│1003│박부장│ 영업│ │1003│ 7000 │
└────┴────┴────┘ └────┴──────┘
↓
merge(left_index=True, right_index=True)
↓
┌────┬────┬────┬──────┐
│ │name│dept│salary│
├────┼────┼────┼──────┤
│1001│김대리│개발 │ 5000 │
│1002│이과장│기획 │ 6000 │
│1003│박부장│영업 │ 7000 │
└────┴────┴────┴──────┘
4. join()
1) 기본: 인덱스로 합치기
# 상품 정보 (인덱스 = 상품코드)
products = pd.DataFrame({
'name': ['노트북', '마우스', '키보드'],
'brand': ['삼성', 'LG', '로지텍']
}, index=['P001', 'P002', 'P003'])
# 재고 정보 (인덱스 = 상품코드)
stocks = pd.DataFrame({
'qty': [10, 50, 30],
'location': ['서울', '부산', '대구']
}, index=['P001', 'P002', 'P003'])
# 간단하게 합치기!
result = products.join(stocks)
print(result)
출력:
name brand qty location
P001 노트북 삼성 10 서울
P002 마우스 LG 50 부산
P003 키보드 로지텍 30 대구
💡 포인트: 인덱스 조인은 join()이 훨씬 간단!
2) 컬럼으로 합치기
# 왼쪽: 컬럼에 ID
authors = pd.DataFrame({
'author_id': [401, 402, 403],
'name': ['김작가', '이작가', '박작가']
})
# 오른쪽: 인덱스에 ID
books = pd.DataFrame({
'title': ['소설', '시집', '에세이']
}, index=[401, 402, 403])
# on 옵션 사용
result = authors.join(books, on='author_id')
print(result)
출력:
author_id name title
0 401 김작가 소설
1 402 이작가 시집
2 403 박작가 에세이
3) 컬럼명 충돌 시
df1 = pd.DataFrame({
'name': ['강남점', '홍대점']
}, index=[1, 2])
df2 = pd.DataFrame({
'name': ['A지점', 'B지점'] # 같은 'name' 컬럼!
}, index=[1, 2])
# lsuffix, rsuffix로 구분
result = df1.join(df2, lsuffix='_left', rsuffix='_right')
print(result)
출력:
name_left name_right
1 강남점 A지점
2 홍대점 B지점
5. 조인 타입 4가지
모든 조인에서 how 옵션으로 선택 가능!
시각적 이해
# 데이터 준비
df_left = pd.DataFrame({
'key': ['A', 'B', 'C'],
'value': [1, 2, 3]
})
df_right = pd.DataFrame({
'key': ['B', 'C', 'D'],
'score': [10, 20, 30]
})
그림으로 보는 조인 타입:
df_left df_right
┌───┬─────┐ ┌───┬─────┐
│key│value│ │key│score│
├───┼─────┤ ├───┼─────┤
│ A │ 1 │ │ B │ 10 │
│ B │ 2 │ │ C │ 20 │
│ C │ 3 │ │ D │ 30 │
└───┴─────┘ └───┴─────┘
═══════════════════════════════════
1️⃣ INNER (교집합)
how='inner' (기본값)
┌───┬─────┬─────┐
│key│value│score│
├───┼─────┼─────┤
│ B │ 2 │ 10 │ ✅ 양쪽 모두 존재
│ C │ 3 │ 20 │ ✅ 양쪽 모두 존재
└───┴─────┴─────┘
═══════════════════════════════════
2️⃣ LEFT (왼쪽 전체)
how='left'
┌───┬─────┬─────┐
│key│value│score│
├───┼─────┼─────┤
│ A │ 1 │ NaN │ ✅ 왼쪽에만 존재
│ B │ 2 │ 10 │ ✅ 양쪽 모두 존재
│ C │ 3 │ 20 │ ✅ 양쪽 모두 존재
└───┴─────┴─────┘
═══════════════════════════════════
3️⃣ RIGHT (오른쪽 전체)
how='right'
┌───┬─────┬─────┐
│key│value│score│
├───┼─────┼─────┤
│ B │ 2 │ 10 │ ✅ 양쪽 모두 존재
│ C │ 3 │ 20 │ ✅ 양쪽 모두 존재
│ D │ NaN │ 30 │ ✅ 오른쪽에만 존재
└───┴─────┴─────┘
═══════════════════════════════════
4️⃣ OUTER (합집합)
how='outer'
┌───┬─────┬─────┐
│key│value│score│
├───┼─────┼─────┤
│ A │ 1 │ NaN │ ✅ 왼쪽에만
│ B │ 2 │ 10 │ ✅ 양쪽 모두
│ C │ 3 │ 20 │ ✅ 양쪽 모두
│ D │ NaN │ 30 │ ✅ 오른쪽에만
└───┴─────┴─────┘
실제 코드
# Inner (기본)
pd.merge(df_left, df_right, on='key', how='inner')
# Left
pd.merge(df_left, df_right, on='key', how='left')
# Right
pd.merge(df_left, df_right, on='key', how='right')
# Outer
pd.merge(df_left, df_right, on='key', how='outer')
6. 실전 팁
1) 언제 뭘 쓸까?
# 컬럼으로 합칠 때 → merge()
pd.merge(df1, df2, on='컬럼명')
# 인덱스로 합칠 때 → join() (더 간단)
df1.join(df2)
# 복잡한 조건 → merge() (더 유연)
pd.merge(df1, df2, left_on='col1', right_index=True)
2) 자주 쓰는 패턴
# 패턴 1: 기본 조인
pd.merge(df1, df2, on='id')
# 패턴 2: Left Join (모든 왼쪽 데이터 유지)
pd.merge(df1, df2, on='id', how='left')
# 패턴 3: 인덱스 조인
df1.join(df2)
# 패턴 4: 컬럼명 충돌 처리
pd.merge(df1, df2, on='id', suffixes=('_x', '_y'))
3) 주의사항
# ⚠️ 컬럼명 충돌 시 suffixes 사용
pd.merge(df1, df2, on='id', suffixes=('_old', '_new'))
# ⚠️ 인덱스를 컬럼으로 변환
df = df.reset_index()
# ⚠️ 컬럼을 인덱스로 변환
df = df.set_index('컬럼명')
비교 요약표
상황 | 추천 | 코드 예시 |
컬럼 기준 합치기 | merge() | pd.merge(df1, df2, on='id') |
인덱스 기준 합치기 | join() | df1.join(df2) |
복잡한 조건 | merge() | pd.merge(..., left_on, right_index) |
간단한 조인 | join() | df1.join(df2) |
핵심 정리
merge() - 만능 도구
# 컬럼 기준
pd.merge(df1, df2, on='컬럼명')
# 인덱스 기준
pd.merge(df1, df2, left_index=True, right_index=True)
# 혼합
pd.merge(df1, df2, left_on='col', right_index=True)
join() - 간편 도구
# 인덱스 기준 (기본)
df1.join(df2)
# 컬럼 기준 (왼쪽만)
df1.join(df2, on='컬럼명')
조인 타입
how='inner' # 교집합 (기본)
how='left' # 왼쪽 전체
how='right' # 오른쪽 전체
how='outer' # 합집합
요약
merge(): 컬럼으로 합칠 때 (대부분)
join(): 인덱스로 합칠 때 (간단)
how='left': 왼쪽 데이터 전부 유지
how='inner': 양쪽 모두 있는 것만
처음엔 merge()만 써도 OK!
'Data Science' 카테고리의 다른 글
Pandas | apply() 함수 (0) | 2025.10.17 |
---|---|
Pandas | 괄호 () 있고 없고의 차이 (0) | 2025.10.15 |