본문 바로가기
Python/Pandas

pandas 데이터 결합 함수 merge()

by 찐남 2022. 2. 13.
pandas 라이브러리 원문을 기반으로 하여 작성하였습니다.

 

pandas는 SQL과 같은 관계형 데이터베이스와 매우 유사한 모든 기능을 갖춘 고성능 인메모리 조인 작업을 제공합니다. 이러한 방법은 다른 오픈 소스 구현(예: R의 base::merge.data.frame) 보다 훨씬 더 나은 성능을 보입니다(어떤 경우에는 10배 이상). 그 이유는 신중한 알고리즘 설계와 DataFrame의 데이터 내부 레이아웃 때문입니다.

 

데이터 결합에 가장 익숙한 도구인 SQL에 익숙하신 분들은 pandas의 merge 문법이 생소해 보일 수도 있어요.

2개의 도구를 비교해 가며 학습하시면 매우 흥미로울 거라고 생각합니다. 

 

pandas는 DataFrame 또는 명명된 Series 객체 간의 모든 표준 데이터베이스 조인 작업을

merge() 단일 함수를 이용하면 가능합니다.

 

 

import pandas as pd

pd.merge(
    left,
    right,
    how="inner",
    on=None,
    left_on=None,
    right_on=None,
    left_index=False,
    right_index=False,
    sort=True,
    suffixes=("_x", "_y"),
    copy=True,
    indicator=False,
    validate=None,
)

 

  • left: DataFrame 또는 명명된 Series 객체
  • right: DataFrame 또는 명명된 Series 객체
  • how: 'left', 'right', 'outer', 'inner', 'cross' 결합 방법 중의 하나를 설정해야 함. 기본값은 inner
결합방법 sql 조인 명령어 설명
left LEFT OUTER JOIN Use keys from left frame only
right RIGHT OUTER JOIN Use keys from right frame only
outer FULL OUTER JOIN Use union of keys from both frames
inner INNER JOIN Use intersection of keys from both frames
cross CROSS JOIN Create the cartesian product of rows of both frames
  • on: 조인할 열 또는 인덱스 수준 이름. left 및 right DataFrame 및/또는 Series 객체에서 모두 찾아야 합니다. 전달되지 않고 left_index와 right_index가 False이면 DataFrames 및/또는 Series의 열 교차가 조인 키로 유추됩니다.
  • left_on: 키로 사용할 왼쪽 DataFrame 또는 Series의 열 또는 인덱스 수준. 열 이름, 인덱스 수준 이름 또는 DataFrame 또는 Series의 길이와 동일한 길이의 배열이 될 수 있습니다.
  • right_on: 키로 사용할 오른쪽 DataFrame 또는 Series의 열 또는 인덱스 수준. 열 이름, 인덱스 수준 이름 또는 DataFrame 또는 Series의 길이와 동일한 길이의 배열이 될 수 있습니다.
  • left_index: True이면 왼쪽 DataFrame 또는 Series의 인덱스(행 레이블)를 조인 키로 사용합니다. MultiIndex(계층적)가 있는 DataFrame 또는 Series의 경우 수준 수는 올바른 DataFrame 또는 Series의 조인 키 수와 일치해야 합니다.
  • right_index: 오른쪽 DataFrame 또는 Series에 대한 left_index와 동일한 사용법
  • sort: 조인 키를 기준으로 결과 DataFrame을 정렬함. 기본값은 True이고, False로 설정하면 많은 경우에 성능이 크게 향상됨
  • suffixes: 겹치는 열에 적용할 문자열 접미사의 튜플입니다. 기본값은 ('_x', '_y')
  • copy: 재인덱싱이 필요하지 않은 경우에도 항상 전달된 DataFrame 또는 명명된 Series 객체에서 데이터(기본값 True)를 복사합니다. 많은 경우 피할 수 없지만 성능/메모리 사용량을 향상시킬 수 있습니다. 복사를 피할 수 있는 경우가 다소 병적이지만 그럼에도 불구하고 이 옵션이 제공됩니다. 
  • indicator: 각 행의 소스에 대한 정보와 함께 _merge라는 출력 DataFrame에 열을 추가합니다. _merge는 범주형이며 병합 키가 '왼쪽' DataFrame 또는 Series에만 나타나는 관찰에 대해 left_only 값을 취하고, 병합 키가 '오른쪽' DataFrame 또는 Series에만 나타나는 관찰에 대해 right_only 값을 취하며, 둘 다 관찰의 병합 키인 경우 both 값을 취합니다.
  • validate: 문자열, 기본값은 없음. 지정된 경우 병합이 지정된 유형인지 확인합니다.
    • “one_to_one” or “1:1”: 병합 키가 왼쪽 및 오른쪽 데이터 세트 모두에서 unique한지 확인
    • “one_to_many” or “1:m”: 병합 키가 왼쪽 데이터 세트에서 unique한지 확인
    • “many_to_one” or “m:1”: 병합 키가 오른쪽 데이터 세트에서 unique한지 확인
    • “many_to_many” or “m:m”: 허용되지만 검사로 이어지지는 않음

※ 색인 수준을 on, left_on 및 right_on 매개변수로 지정하는 지원이 버전 0.23.0에 추가되었습니다. 

명명된 Series 개체 병합에 대한 지원이 버전 0.24.0에 추가되었습니다.

 

 


 

반환 유형은 왼쪽과 동일합니다. 

왼쪽이 DataFrame 또는 명명된 Series이고 

오른쪽이 DataFrame의 하위 클래스인 경우,

반환 유형은 여전히 DataFrame입니다.

merge는 pandas 네임스페이스의 함수이며,

DataFrame 인스턴스 메서드 merge()로도 사용할 수 있으며,

DataFrame 호출은 암시적으로 조인의 왼쪽 개체로 간주됩니다.

관련 join() 메서드는 인덱스 온 인덱스(기본값) 및 

인덱스 온 인덱스 조인에 대해 내부적으로 병합을 사용합니다. 

인덱스에서만 조인하는 경우 DataFrame.join을 사용하여 입력을 절약할 수 있습니다.

 


 

병합 방법에 대한 간략한 입문서(관계 대수학)

SQL과 같은 관계형 데이터베이스에 숙련된 사용자는 두 개의 SQL 테이블 유사 구조(DataFrame 개체) 간의 조인 작업을 설명하는 데 사용되는 용어에 익숙할 것입니다. 이해하는 데 매우 중요한 몇 가지 경우를 고려해야 합니다.

 

  • one-to-one joins: 예를 들어 인덱스에서 두 DataFrame 개체를 결합할 때(unique한 값을 포함해야 함).
  • many-to-one joins: 예를 들어 인덱스(unique)를 다른 DataFrame의 하나 이상의 열에 조인할 때.
  • many-to-many joins: 열에 열 결합.

※ 열의 열을 조인할 때(다대다 조인 가능성이 있음) 전달된 DataFrame 개체의 모든 인덱스는 무시됩니다.

 

다대다 조인 사례의 결과를 이해하는 데 시간을 할애할 가치가 있습니다. SQL/표준 관계형 대수학에서 키 조합이 두 테이블에 두 번 이상 나타나면 결과 테이블에는 연결된 데이터의 데카르트 곱이 표시됩니다. 다음은 하나의 고유한 키 조합이 있는 매우 기본적인 예입니다.

 


결합 예시

 

## 'left' DataFrame과 'right' DataFrame을 결합 키 'key'를 활용해서 inner join 결합
result = pd.merge(left, right, on="key")

## 'left' DataFrame 과 'right' DataFrame 을 결합키 'key1'과 'key2'를 활용해서 inner join 결합
result = pd.merge(left, right, on=["key1", "key2"])

## 'left' DataFrame 과 'right' DataFrame 을 결합키 'key1'과 'key2'를 활용해서 left join 결합
result = pd.merge(left, right, how="left", on=["key1", "key2"])

## 'left' DataFrame 과 'right' DataFrame 을 결합키 'key1'과 'key2'를 활용해서 right join 결합
result = pd.merge(left, right, how="right", on=["key1", "key2"])

## 'left' DataFrame 과 'right' DataFrame 을 결합키 'key1'과 'key2'를 활용해서 outer join 결합
result = pd.merge(left, right, how="outer", on=["key1", "key2"])

## 'left' DataFrame 과 'right' DataFrame 을 결합키 'key1'과 'key2'를 활용해서 inner join 결합
result = pd.merge(left, right, how="inner", on=["key1", "key2"])

## 'left' DataFrame 과 'right' DataFrame 을 cartesian product 결합
result = pd.merge(left, right, how="cross")

## 'left' DataFrame 과 'right' DataFrame 을 결합키 'B'를 활용해서 outer join 결합
## left와 right DataFrame이 결합키 'B' 기준으로 unique 한 지 검증함
## unique하지 않으면 에러 발생함
## 에러 발생 예시
## MergeError: Merge keys are not unique in right dataset; not a one-to-one merge
result = pd.merge(left, right, on="B", how="outer", validate="one_to_one")

## 'df1' DataFrame과 'df2' DataFrame을 결합 키 'col1'을 활용해서 outer join 결합
## 결합된 DataFrame에 대해서 df1에만 존재하는지, df2에만 존재하는지,
## df1과 df2에 모두 존재하는지를 새로운 칼럼 '_merge'를 생성하여 저장함
pd.merge(df1, df2, on="col1", how="outer", indicator=True)

## 결합된 DataFrame에 대해서 df1에만 존재하는지, df2에만 존재하는지,
## df1과 df2에 모두 존재하는지를 새로운 칼럼 'indicator_column'를 생성하여 저장함
df2에 모두 존재하는지를 새로운 칼럼 '_merge'를 생성하여 저장함
pd.merge(df1, df2, on="col1", how="outer", indicator="indicator_column")

 

자세한 예제는 간단한 DataFrame을 생성하셔서 이것저것 해 보시는 게

정확히 이해하는 데 가장 좋을 거 같습니다.

 

 

반응형

댓글