python에서 여러 테이블을 처리할 때 서로 다른 테이블을 붙이거나 관계형으로 이어서 활용할 경우가 왕왕 있습니다.
이 때 concat, merge를 주로 활용하는데 저처럼 마구잡이로 배운사람은 헷갈리는 경우가 많아서 도움이 되었으면 하는 마음에 주요 기능을 정리합니다.
concat은 좀 더 붙이는 기능 위주고 merge는 관계형 데이터, sql을 하는 것과 비슷하다고 생각하면 헷갈릴 일이 적을듯합니다.
선요약
🔥 concat() vs merge() 비교 정리
비교 항목 | concat | merge |
주요 기능 | 여러 DataFrame을 단순히 이어붙임 | 공통된 컬럼(키)을 기준으로 병합 |
유사한 SQL 연산 | UNION (행 추가) | JOIN (INNER, OUTER, LEFT, RIGHT) |
병합 기준 | 컬럼이 같아야 정렬됨 (없으면 NaN 처리) | 공통된 키(Column) 값 기준으로 병합 |
인덱스 활용 | ignore_index=True로 리셋 가능 | left_index=True, right_index=True 가능 |
열(Column) 다를 때 | 자동으로 NaN 채움 | join="inner"로 공통 컬럼만 선택 가능 |
컬럼명이 다를 때 | 자동 NaN 처리 (axis=1로 해결) | left_on, right_on 옵션 필요 |
📌 pandas.concat 기본 원칙
pandas.concat()은 여러 개의 DataFrame이나 Series를 하나로 합칠 때 사용됩니다. 주로 다음과 같은 원칙을 따릅니다.
- 기본적으로 인덱스를 유지
- concat()은 별도로 설정하지 않으면 기존 인덱스를 그대로 유지합니다.
- 새로운 인덱스를 만들려면 ignore_index=True를 사용합니다.
- 축(Axis) 방향 설정 가능
- axis=0 (기본값, 세로 방향): 행(row) 단위로 합침 → 데이터가 아래로 추가됨
- axis=1 (가로 방향): 열(column) 단위로 합침 → 데이터가 옆으로 확장됨
- 공통 컬럼이 없을 경우 NaN 처리
- 컬럼(열)이 다르면 자동으로 NaN을 채워 넣습니다.
- join="inner" 옵션을 사용하면 공통 컬럼만 유지할 수 있습니다.
🛠 사용 예시
1️⃣ 세로 방향(axis=0) 기본 연결
두 개의 데이터프레임을 행(row) 기준으로 합치기
import pandas as pd
df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [5, 6], 'B': [7, 8]})
result = pd.concat([df1, df2]) # 기본 옵션 (axis=0)
print(result)
결과
A B
0 1 3
1 2 4
0 5 7
1 6 8
➡ 기존 인덱스 유지 (동일한 숫자 인덱스 발생)
🎯 해결법: ignore_index=True 추가
result = pd.concat([df1, df2], ignore_index=True)
print(result)
A B
0 1 3
1 2 4
2 5 7
3 6 8
➡ 인덱스가 새롭게 리셋됨
2️⃣ 가로 방향(axis=1) 연결
같은 길이의 데이터프레임을 옆으로 확장
df1 = pd.DataFrame({'A': [1, 2]})
df2 = pd.DataFrame({'B': [3, 4]})
result = pd.concat([df1, df2], axis=1)
print(result)
#결과
A B
0 1 3
1 2 4
➡ 새로운 열이 추가됨
3️⃣ 컬럼이 다를 때 (NaN 처리)
컬럼이 다를 경우 NaN이 채워짐
df1 = pd.DataFrame({'A': [1, 2]})
df2 = pd.DataFrame({'B': [3, 4]})
result = pd.concat([df1, df2])
print(result)
결과
A B
0 1.0 NaN
1 2.0 NaN
0 NaN 3.0
1 NaN 4.0
➡ 공통 컬럼이 없으므로 NaN 발생
🎯 해결법: axis=1로 병합하면 문제 해결
result = pd.concat([df1, df2], axis=1)
print(result)
결과
A B
0 1 3
1 2 4
➡ 컬럼을 유지하면서 연결됨
4️⃣ 공통 컬럼만 유지 (join='inner')
join="inner" 옵션을 사용하면 공통 컬럼만 유지 가능
df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'B': [5, 6], 'C': [7, 8]})
result = pd.concat([df1, df2], join='inner', ignore_index=True)
print(result)
결과
B
0 3
1 4
2 5
3 6
➡ 공통 컬럼 B만 남음
✅ pandas.concat() 요약 정리
axis=0 | 기본값, 세로 방향(행 추가) |
axis=1 | 가로 방향(열 추가) |
ignore_index=True | 인덱스를 새롭게 리셋 |
join="inner" | 공통 컬럼만 유지 |
join="outer" | 기본값, 모든 컬럼 유지 (NaN 포함) |
📌 핵심 포인트
- 같은 컬럼을 가진 데이터 합칠 땐 axis=0
- 다른 컬럼을 가진 데이터 합칠 땐 axis=1
- 인덱스 초기화하려면 ignore_index=True
- 공통 컬럼만 유지하려면 join="inner"
pandas.merge()는 데이터프레임을 공통된 열(또는 인덱스)을 기준으로 합치는 함수입니다.
데이터베이스의 JOIN(조인) 연산과 유사한 방식으로 동작합니다.
📌 merge() 기본 원칙
1️⃣ 공통된 컬럼(키, Key)을 기준으로 병합
- 두 데이터프레임에서 같은 값을 가진 행들만 합쳐집니다.
- on="컬럼명"을 지정해야 함. (생략하면 자동으로 같은 이름의 컬럼을 찾음)
2️⃣ 병합 방식 선택 가능 (how 옵션)
방식설명
inner | (기본값) 공통된 값이 있는 행만 병합 (교집합) |
outer | 모든 데이터를 포함 (합집합, 없는 값은 NaN) |
left | 왼쪽 데이터 기준으로 병합 (오른쪽에 없는 값은 NaN) |
right | 오른쪽 데이터 기준으로 병합 (왼쪽에 없는 값은 NaN) |
3️⃣ 공통 컬럼 이름이 다를 경우 left_on, right_on 사용
- 서로 다른 이름의 컬럼을 기준으로 병합 가능
🛠 사용 예시
1️⃣ 기본적인 inner join (공통 컬럼 기준 병합)
import pandas as pd
df1 = pd.DataFrame({'ID': [1, 2, 3], 'Name': ['Alice', 'Bob', 'Charlie']})
df2 = pd.DataFrame({'ID': [2, 3, 4], 'Score': [90, 85, 70]})
result = pd.merge(df1, df2, on='ID') # 기본값 how='inner'
print(result)
결과 (inner join이므로 공통된 ID만 병합)
ID Name Score
0 2 Bob 90
1 3 Charlie 85
➡ ID=1, ID=4는 다른 데이터프레임에 없어서 제외됨
2️⃣ outer join (모든 데이터를 포함)
result = pd.merge(df1, df2, on='ID', how='outer')
print(result)
✅ 결과 (outer join: 없는 값은 NaN)
ID Name Score
0 1 Alice NaN
1 2 Bob 90.0
2 3 Charlie 85.0
3 4 NaN 70.0
➡ 모든 데이터를 유지하며, 없는 값은 NaN으로 표시
3️⃣ left join (왼쪽 데이터프레임 기준)
result = pd.merge(df1, df2, on='ID', how='left')
print(result)
결과 (left join: 왼쪽 데이터프레임 기준)
ID Name Score
0 1 Alice NaN
1 2 Bob 90.0
2 3 Charlie 85.0
➡ 왼쪽 데이터프레임(df1)의 모든 값을 유지하고, 없는 값은 NaN
4️⃣ right join (오른쪽 데이터프레임 기준)
result = pd.merge(df1, df2, on='ID', how='right')
print(result)
결과 (right join: 오른쪽 데이터프레임 기준)
ID Name Score
0 2 Bob 90
1 3 Charlie 85
2 4 NaN 70
➡ 오른쪽 데이터프레임(df2)의 모든 값을 유지하고, 없는 값은 NaN
5️⃣ 컬럼명이 다를 때 left_on, right_on 사용
df1 = pd.DataFrame({'Emp_ID': [1, 2, 3], 'Name': ['Alice', 'Bob', 'Charlie']})
df2 = pd.DataFrame({'Worker_ID': [2, 3, 4], 'Score': [90, 85, 70]})
result = pd.merge(df1, df2, left_on='Emp_ID', right_on='Worker_ID', how='inner')
print(result)
결과 (Emp_ID와 Worker_ID를 기준으로 병합)
Emp_ID Name Worker_ID Score
0 2 Bob 2 90
1 3 Charlie 3 85
➡ 컬럼명이 다르더라도 매칭 가능! (Emp_ID == Worker_ID)
6️⃣ 여러 개의 컬럼을 기준으로 병합
df1 = pd.DataFrame({'ID': [1, 2, 3], 'Subject': ['Math', 'Science', 'History'], 'Score1': [90, 85, 88]})
df2 = pd.DataFrame({'ID': [1, 2, 3], 'Subject': ['Math', 'Science', 'History'], 'Score2': [80, 95, 75]})
result = pd.merge(df1, df2, on=['ID', 'Subject'], how='inner')
print(result)
결과 (ID + Subject 두 개의 컬럼을 기준으로 병합)
ID Subject Score1 Score2
0 1 Math 90 80
1 2 Science 85 95
2 3 History 88 75
➡ 두 개 이상의 컬럼을 동시에 키로 사용할 수도 있음
✅ pandas.merge() 요약 정리
on="컬럼명" | 기준이 되는 컬럼 설정 |
how="inner" | 기본값, 공통된 값이 있는 행만 유지 |
how="outer" | 모든 행 포함, 없는 값은 NaN |
how="left" | 왼쪽 데이터프레임 기준으로 병합 |
how="right" | 오른쪽 데이터프레임 기준으로 병합 |
left_on="컬럼명", right_on="컬럼명" | 컬럼명이 다를 때 사용 |
on=["컬럼1", "컬럼2"] | 여러 개의 컬럼을 기준으로 병합 |
📌 핵심 포인트
- merge()는 공통된 컬럼(키)을 기준으로 데이터 병합
- how 옵션으로 INNER, OUTER, LEFT, RIGHT JOIN 가능
- 컬럼 이름이 다르면 left_on, right_on 사용
- 여러 개의 컬럼을 동시에 병합 가능
'생각은축복이다' 카테고리의 다른 글
knime에 anaconda 를 활용해 python script 활용하기 (0) | 2025.03.07 |
---|---|
다크 패턴(Dark Patterns)이란 무엇인가? 네이버 쇼핑을 예로 살펴보자 (0) | 2025.03.05 |
쉽게 이해하는 대출 관련 지표: DSR, DTI, LTV (0) | 2025.03.01 |
모델의 정확도만 믿어도 될까요?— 신뢰성을 결정하는 Calibration의 중요성 (0) | 2025.02.27 |
SQL 문자열 검색 & 편집 꿀팁 (0) | 2025.02.14 |