프로파일링 자동화와 식별자 검증기
데이터 소스 조사와 프로파일링
프로파일링 자동화와 식별자 검증기
데이터 소스 조사와 프로파일링 > 데이터 소스 조사와 프로파일링
- 프로파일링 다섯 검진 항목을 안다
- 재사용 가능한 프로파일러를 구현한다
- ISO 6346 체크디지트 검증기로 품질 CQ 를 코드로 만든다
프로파일링 — 데이터의 건강검진
프로파일링(profiling)은 데이터를 쓰기 전에 그 실태를 정량 조사하는 것입니다. 검진 항목은 다섯입니다.
- 스키마 추론: 필드명·타입·포맷 — 문서와 실물이 같은가
- 완전성: 필드별 결측률 — CQ가 요구하는 필드가 실제로 채워져 있는가
- 고유성·카디널리티: 키 후보의 중복 여부, 코드 필드의 값 종류 수
- 정합성: 식별자 유효성(체크디지트), 코드값의 사전 일치, 시각의 순서(입항<출항)
- 커버리지: 기간 범위, 항만 범위 — "부산항 2년치"인가 "전국 3개월"인가
핵심 태도는 이겁니다. 프로파일링 리포트가 곧 CQ 판정의 증거입니다. "PL-09(선사별 물동량)가 가능하다"고 말하려면 선사 필드의 결측률과 표기 일관성을 숫자로 제시해야 합니다.
프로파일링 자동화 — 재사용 가능한 파이프라인
매 데이터셋마다 손으로 검진하지 않습니다. 한 번 짜서 모든 CSV에 돌리는 프로파일러를 만듭니다.
import pandas as pd
from pathlib import Path
def profile(csv_path: str, encoding="utf-8") -> dict:
"""CSV 1개의 건강검진 리포트 생성"""
df = pd.read_csv(csv_path, encoding=encoding, dtype=str) # 우선 전부 문자로
n = len(df)
report = {"file": Path(csv_path).name, "rows": n, "cols": len(df.columns), "fields": []}
for col in df.columns:
s = df[col]
report["fields"].append({
"name": col,
"missing_pct": round(s.isna().mean() * 100, 2), # 완전성
"unique": int(s.nunique()), # 카디널리티
"unique_pct": round(s.nunique() / max(n,1) * 100, 2), # 키 후보 판별
"samples": s.dropna().unique()[:5].tolist(), # 눈으로 확인용
})
return report
실전 요령 세 가지
① 일단 전부 문자열(dtype=str)로 읽습니다. pandas의 자동 타입 추론이 "0으로 시작하는 코드"(계선장소 코드 등)를 숫자로 바꿔 훼손하는 사고를 막습니다. 타입 판정은 프로파일 결과를 보고 사람이 확정합니다.
② unique_pct 가 100%에 가까운 필드가 키 후보, 낮은 필드가 코드·분류 후보입니다.
③ samples 5개는 반드시 눈으로 봅니다. 통계가 못 잡는 이상(한글 깨짐, 단위 혼재)은 눈이 잡습니다.
식별자 검증기 — CO-03 의 실전 구현
ISO 6346 체크디지트를 직접 구현합니다. 컨테이너 번호의 각 문자를 수치화(A=10부터, 단 11의 배수는 건너뜀)하고 자릿수별 2ⁿ 가중 합을 11로 나눈 나머지가 체크디지트입니다.
def iso6346_check(container_no: str) -> bool:
"""ISO 6346 컨테이너 번호 체크디지트 검증 (예: 'MSKU1234567')"""
cn = container_no.replace(" ", "").upper()
if len(cn) != 11 or not cn[:4].isalpha() or not cn[4:].isdigit():
return False
# 문자 값표: A=10, B=12, ... (11의 배수 건너뜀)
letter_vals, v = {}, 10
for ch in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
letter_vals[ch] = v
v += 1
if v % 11 == 0: v += 1
vals = [letter_vals[c] if c.isalpha() else int(c) for c in cn[:10]]
total = sum(val * (2 ** i) for i, val in enumerate(vals))
return total % 11 % 10 == int(cn[10])
이 40줄이 하는 일의 의미가 큽니다. 데이터 품질 CQ가 코드가 됐습니다. 프로파일러에 이 검증기를 꽂으면 어떤 화물 데이터가 와도 CO-03("체크디지트 오류 레코드는?")의 답이 자동 산출됩니다. 다음 모듈의 골든 데이터셋에서 이 함수의 판정이 정답지가 됩니다.
실습
- 확보한 CSV 하나에
profile()을 돌리고 리포트를 읽습니다. - unique_pct 상위 3개 필드를 키 후보로 지목하고, 실제로 키가 맞는지 눈으로 확인합니다.
iso6346_check를 유효한 번호와 한 글자 바꾼 번호에 각각 돌려 판정이 갈리는지 확인합니다.- 프로파일러에 검증기를 연결해 오류 레코드 수를 셉니다.