2025.02.24 - [프로그래밍/Python 관련 정보] - [Pandas] Table of Contents
데이터를 병합에 대해서 간단히 정리하고 Pandas 정리는 얼추 마치려고 합니다.
1. pd.merge
(1) Syntax
pd.merge(left, right, how="inner", on=None, left_on=None, right_on=None, left_index=False, right_index=False, suffixes=("_x", "_y"), copy=None, indicator=False, validate=None)
(2) 입력 인자
- left, right : 병합할 두 개의 DataFrame
- how : 병합 방식 ("inner", "outer", "left", "right") 병합의 기본 개념은 SQL때와 동일합니다.
참고) https://trillionver2.tistory.com/entry/SQL-%EA%B8%B0%EC%B4%88-SQL-join - on : 공통 컬럼(키)을 기준으로 병합 (컬럼명이 같을 때 사용)
- left_on, right_on : 서로 다른 키를 기준으로 병합할 경우 각각 지정
left_index, right_index : 인덱스를 기준으로 병합할 경우 True 설정 - suffixes : 겹치는 컬럼명에 대한 접미사 지정 (기본값 ("_x", "_y"))
- Indicator : 추가 열에 아래 정보를 표기할지 여부
'left_only' : 왼쪽 데이터프레임에만 있는 데이터
'right_only' : 오른쪽 데이터프레임에만 있는 데이터
'both': 양쪽 데이터프레임에 모두 있는 데이터 - copy : 병합된 결과를 새로운 DataFrame으로 복사할 지 여부를 결정
- validate : 병합 방식이 올바른지 검사하여 데이터의 무결성을 확인. 잘못된 병합이 발생하면 MergeError 발생.
옵션 설명 "one_to_one" 각 키 값이 한 번만 등장해야 함 (1:1 병합) "one_to_many" 왼쪽 DataFrame은 한 번, 오른쪽 DataFrame은 여러 번 등장 가능 (1:N 병합) "many_to_one" 왼쪽 DataFrame은 여러 번, 오른쪽 DataFrame은 한 번 등장 가능 (N:1 병합) "many_to_many" 양쪽 DataFrame 모두 여러 번 등장 가능 (기본적으로 검사 안 함)
예시를 통해 살펴볼까요?
더보기
아래와 같은 데이터 프레임이 있다고 해보겠습니다.
import pandas as pd
df1 = pd.DataFrame({"key": ["A", "B", "C"], "value1": [1, 2, 3]})
df2 = pd.DataFrame({"key": ["B", "C", "D"], "value2": [4, 5, 6]})
On 을 사용한 병합
import pandas as pd
df1 = pd.DataFrame({"key": ["A", "B", "C"], "value1": [1, 2, 3]})
df2 = pd.DataFrame({"key": ["B", "C", "D"], "value2": [4, 5, 6]})
merged_df = pd.merge(df1, df2, on="key", how="inner")
print(merged_df)
left_on, right_on을 사용한 병합 (column명이 다를경우)
df1 = pd.DataFrame({"id": [1, 2, 3], "value1": [10, 20, 30]})
df2 = pd.DataFrame({"user_id": [2, 3, 4], "value2": [40, 50, 60]})
merged_df = pd.merge(df1, df2, left_on="id", right_on="user_id", how="inner")
print(merged_df)
left_index, right_index를 사용한 병합(인덱스 활용)
df1 = pd.DataFrame({"value1": [10, 20, 30]}, index=["A", "B", "C"])
df2 = pd.DataFrame({"value2": [40, 50, 60]}, index=["B", "C", "D"])
merged_df = pd.merge(df1, df2, left_index=True, right_index=True, how="inner")
print(merged_df)
Column명이 겹칠 때 suffixes 사용
df1 = pd.DataFrame({"key": ["A", "B"], "value": [1, 2]})
df2 = pd.DataFrame({"key": ["A", "B"], "value": [3, 4]})
merged_df = pd.merge(df1, df2, on="key", how="inner", suffixes=("_df1", "_df2"))
print(merged_df)
Validate을 활용한 검증
df1 = pd.DataFrame({"key": ["A", "B", "C"], "value1": [1, 2, 3]})
df2 = pd.DataFrame({"key": ["A", "A", "B"], "value2": [4, 5, 6]})
# one_to_one 검증 (실패)
pd.merge(df1, df2, on="key", validate="one_to_one")
MergeError: Merge keys are not unique in right dataset; not a one-to-one merge
2. pd.concat
(1) Syntax
pd.concat(objs, axis=0, join="outer", ignore_index=False, keys=None, names=None, verify_integrity=False, copy=True)
(2) 입력인자
- objs :병합할 여러 개의 DataFrame 또는 Series (리스트 형태로 전달)
- axis : 0 (Default) → 세로 방향(행 기준) 병합 / 1 → 가로 방향(열 기준) 병합
- join : "outer" (Default) → 모든 데이터를 포함 (공통된 인덱스가 없으면 NaN 채움) / "inner" → 공통된 인덱스만 유지
- ignore_index : False (기본값) → 기존 인덱스 유지 / True → 새로운 인덱스를 부여 (0부터 시작)
- keys: 그룹을 구분하는 키 값 지정 (MultiIndex 생성)
- names: keys를 사용할 경우 MultiIndex의 이름 지정
- verify_integrity: True로 설정하면 중복된 인덱스가 있을 경우 오류 발생
- copy: 데이터를 복사할지 여부 (copy=False로 설정하면 메모리 절약 가능)
(3) 예시
더보기
아래와 같은 데이터프레임이 있다고 해보겠습니다.
import pandas as pd
df1 = pd.DataFrame({"A": ["A0", "A1"], "B": ["B0", "B1"]})
df2 = pd.DataFrame({"A": ["A2", "A3"], "B": ["B2", "B3"]})
df4 = pd.DataFrame({"C": ["C1", "C2"]}, index=[1, 2])
join='inner'을 사용한 공통 인덱스 병합
result = pd.concat([df1, df4], axis=1, join="inner")
print(result)
A B C
1 A1 B1 C1
참고) 과거에는 df.append()를 사용해 DataFrame을 추가할 수 있었지만, pandas 1.4.0부터 append()가 폐지(deprecated) 되면서 pd.concat() 사용이 권장됨.
마지막으로 두 방법의 차이를 한번 정리하고 마치겠습니다.
pd.concat() | pd.merge() | |
기준 | 인덱스 또는 칼럼 없음 | 특정 컬럼(on) 기준 병합 |
방향 | axis=0 (행) 또는 axis=1 (열) | 기본적으로 axis=1 (가로 병합) |
SQL 비교 | UNION과 유사 | JOIN과 유사 |
'프로그래밍 > Python 관련 정보' 카테고리의 다른 글
[Phycharm] Table of Contents (0) | 2025.02.26 |
---|---|
[Pandas] Table of Contents (0) | 2025.02.24 |
[Pandas] 데이터 재구조화 (0) | 2025.02.23 |
[Pandas] Advanced Indexing - filter (0) | 2025.02.23 |
[Pandas] Advanced Indexing - query (0) | 2025.02.23 |