본문으로 바로가기
TaeyoungKim.dev

pandas merge 뒤 행이 늘어나는 이유: 중복 키와 조인 카디널리티 확인

파이썬작성 약 2분 읽기TaeyoungKim
LinkedInX

pandas merge 뒤 행 수가 갑자기 늘어나면 조인 키가 양쪽에 몇 번씩 나오는지 먼저 보자. 같은 고객 ID가 주문 표에 두 번, 고객 표에도 두 번 있으면 네 조합이 만들어진다. 결과 행이 늘어난 이유를 보기 위해 작은 표부터 만들자.

python
import pandas as pd

orders = pd.DataFrame({"order": ["A", "B"], "customer_id": [1, 1]})
customers = pd.DataFrame({"customer_id": [1, 1], "tier": ["X", "Y"]})

merged = orders.merge(customers, on="customer_id", how="left")
assert len(merged) == 4

주문 A는 고객 정보 X·Y에 각각 붙고, 주문 B도 X·Y에 각각 붙는다. 주문이 네 개 생긴 것이 아니라 조인 결과가 네 행으로 늘어난 것이다. 이 상태로 금액을 합산하면 같은 주문이 여러 번 계산될 수 있다.

주문붙은 고객 등급
AX, Y
BX, Y

오른쪽 표에서 고객 ID가 한 행뿐이었다면 결과도 주문 두 행이었을 것이다. 조인 전에 기대한 관계를 먼저 정해야 행 증가가 정상인지 오류인지 판단할 수 있다.

조인 전에 키의 정체를 확인한다

고객 표의 customer_id가 한 고객을 하나만 가리킨다는 가정이라면 오른쪽 표의 중복을 검사한다.

예제에서는 1이 양쪽에 두 번씩 있으므로 2 × 2 = 4행이다. 키가 고유하다는 가정을 코드로 확인해야 한다.

python
duplicates = customers[customers["customer_id"].duplicated(keep=False)]
assert len(duplicates) == 2

중복을 drop_duplicates로 즉시 지우면 원본 데이터의 오류를 감출 수 있다. 어떤 행이 최신인지, 여러 행이 실제로 허용되는 관계인지 업무 규칙을 먼저 정해야 한다.

validate로 기대한 관계를 코드에 남긴다

many_to_one은 왼쪽에는 여러 행, 오른쪽에는 키당 한 행을 기대한다. 지금 데이터에는 맞지 않으므로 MergeError가 나야 한다.

python
from pandas.errors import MergeError

try:
    orders.merge(customers, on="customer_id", how="left", validate="many_to_one")
except MergeError:
    pass  # 오른쪽 고객 키 중복을 예상한 테스트
else:
    raise AssertionError("중복 고객 키를 놓쳤습니다")

오류가 났다고 drop_duplicates로 먼저 지우지 말자. X와 Y 중 어느 행이 맞는지 원천 데이터의 식별 규칙·갱신 시각을 확인해야 한다. 조인 전후 행 수, 오른쪽 키 중복 수, 매칭되지 않은 주문 수를 함께 기록하면 어디에서 데이터가 달라졌는지 좁히기 쉽다. 대량 데이터에서는 중복 조인이 메모리를 빠르게 늘릴 수 있으므로 합치기 전에 카디널리티를 검사하는 편이 안전하다.

핵심 요약

merge 뒤 행 증가의 대표 원인은 조인 키 중복이다. 조인 카디널리티를 업무 규칙으로 정하고, 중복을 확인한 뒤 validate로 코드에 선언하자. 임의 deduplication보다 왜 중복됐는지 파악하는 것이 데이터 품질에 중요하다.

작성자

TaeyoungKim

기초 개념을 구현과 검증, 실제 운영 판단까지 연결해 기록합니다.

#Python#pandas#merge#데이터 분석

함께 읽으면 좋은 글