Community코딩 & 개발github.com

ZrobDev/data-cleaning

CSV, Parquet 또는 XLSX 파일을 프로파일링, 정리, 중복 제거, 정규화하고, 날짜/통화/ID를 강제 변환하거나 OCR 문서와 시스템 내보내기 파일을 조정할 때 사용합니다. 행 수 불일치, 선행 제로 손실, 중복, 합계 대조, 안티 조인, 예외 보고서를 다룹니다.

data-cleaning란 무엇인가요?

이 스킬은 데이터 정리 및 조정 작업을 위한 포괄적인 프레임워크를 제공합니다. 로컬 파일을 위해 DuckDB 2.0 SQL 또는 Polars 2.x 지연 API를 기본 도구로 사용하며, pandas는 라이브러리에서 강제하는 경우에만 사용합니다. 핵심 원칙은 '절대 조용히 수정하지 않음'으로, 모든 강제 변환, 제거, 기본값 대체 또는 병합은 계산되어 보고됩니다. 각 정리 단계는 `(입력 행 수, 출력 행 수, 변경된 행 수, 이유)` 형식으로 추적되며, 캐스트 실패는 NULL과 개수로 처리될 뿐 행이 삭제되거나 값이 추측되지 않습니다. 절차는 읽기 전용 프로파일링, 키/세분성/유형 결정, 작은 계산 단계의 파이프라인으로 정리, 두 소스가 있을 경우 조정, 그리고 모든 개수를 포함한 예외 보고서 및 실행 요약 생성의 5단계로 구성됩니다. 조정 감사는 제어 합계, 키 매칭 (양방향 안티 조인), 매칭 쌍의 필드 비교, 오류 분류, 최종 균형 검증을 포함한 엄격한 방법론을 따릅니다.

지원 대상~Claude Code~Codex CLI~Cursor
Part ofMobile
npx skills add https://github.com/ZrobDev/data-engineering-skills/tree/HEAD/skills/data-cleaning

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

데이터 정리 및 조정

기본 도구: 로컬 파일의 경우 DuckDB 2.0 SQL 또는 polars 2.x 지연 API (scan_csv, scan_parquet). pandas는 라이브러리에서 강제하는 경우에만 사용합니다. Python은 uv를 통해 실행하고, ruff로 린트합니다. Polars 2.0 또는 DuckDB 2.0에서 변경된 API 세부 사항은 현재 문서와 대조하여 확인하세요 (references/landscape-2026-11.md 참조).

절대 조용히 수정하지 않음

모든 강제 변환, 제거, 기본값 대체 또는 병합은 계산되고 보고됩니다. 정리 단계는 (입력 행 수, 출력 행 수, 변경된 행 수, 이유) 형식입니다. 캐스트 실패는 NULL과 개수로 처리되며, 행이 삭제되거나 값이 추측되지 않습니다. 원시 입력은 그대로 두고 정리된 출력은 새 경로에 씁니다. 단계의 개수가 예상과 다르면 멈추고 계속 진행하는 대신 보고합니다.

절차

  1. 프로파일링 (읽기 전용). 2. 키, 세분성 및 유형 결정. 3. 작은 계산 단계의 파이프라인으로 정리. 4. 두 소스가 있을 경우 조정. 5. 모든 개수와 함께 예외 및 실행 요약 출력.

1. 건드리기 전에 프로파일링

먼저 모든 열을 텍스트로 읽습니다 (DuckDB에서는 all_varchar=true, polars에서는 infer_schema=False). 샘플에 대한 추론은 00123을 123으로, 혼합 열을 첫 번째 행의 유형으로 조용히 변경하기 때문입니다. 그런 다음 열별로 계산: 행 수, null/빈 문자열 비율, 고유 값 개수, 최소/최대 (텍스트 및 파싱된 값으로), 최단/최장 길이, 유형 패턴 (정수, 소수, ISO 날짜, 기타)과 일치하는 값의 비율. DuckDB의 SUMMARIZE는 대부분을 한 번의 호출로 수행합니다.

정리 전 기록: 총 행 수, 고유 후보 키 개수, 키당 최대 행 수, 정확히 발견된 헤더 (후행 공백, BOM, 중복 이름). 후보 키는 정규화 후 고유 값 개수가 행 수와 같은 경우에만 키입니다. 테스트하고 가정하지 마십시오.

다음 항목을 확인하십시오: 전체 행 중복, 파일 중간에 반복된 헤더, 데이터 내부의 바닥글/합계 행, 센티널 값 ("N/A", "-", "0000-00-00", 9999-12-31), 혼합 인코딩, 식별자인 숫자 열.

2. 유형 및 파싱

  • ID, 우편 번호, 계좌 및 전화 번호는 항상 문자열입니다. 문서화된 너비가 있는 경우에만 제로 패딩 너비를 규칙으로 저장합니다 (lpad 사용). 그렇지 않으면 읽은 대로 유지합니다.
  • 날짜: 열별로 명시적 형식으로 파싱합니다 (try_strptime / str.to_date(format, strict=False)). 엔진이 월/일 순서를 추측하도록 하지 마십시오. 문서화된 순서가 없는 모호한 값 (03/04/2026)은 동전 던지기가 아니라 예외입니다. 시간대 결정을 명시적으로 유지하십시오.
  • 금액: 정수 하위 단위 또는 DECIMAL(p,s)로 파싱하고 절대 float를 사용하지 마십시오. 로케일 규칙에 따라 통화 기호와 천 단위 구분 기호를 제거합니다: 1.234,56과 1,234.56은 다른 로케일이므로 소스별로 결정하고 모든 값이 선택한 패턴과 일치하는지 확인하십시오. 괄호와 후행 마이너스는 음수입니다. 행별로 통화를 기록하고 통화 간에 합산하지 마십시오.
  • 부울 및 열거형: 명시적 테이블에서 매핑하고, 매핑되지 않은 값은 예외로 보냅니다.
  • 각 캐스트 후에 '캐스트 전 널이 아닌 값 수'에서 '캐스트 후 널이 아닌 값 수'를 뺍니다. 그 숫자는 강제 변환 실패 횟수이며 보고서에 포함됩니다.

3. 정규화

원본 열이 아닌 파생된 일치 키에 적용하여 원시 값을 사용할 수 있도록 유지합니다: 유니코드 NFKC, 트림, 내부 공백 축소, 케이스폴드, 제로 너비 및 줄 바꿈 없는 공백 제거. NFKC는 정보 손실이 있습니다 (합자, 전각 형태, 위 첨자). 이는 일치를 위한 것이며 표시에는 적합하지 않습니다. 식별자의 경우 구분 기호 (-, /, 공백)도 제거하고 O/0 및 I/1 처리를 명시적으로 결정합니다. NFKC는 DuckDB 코어 SQL에 없습니다. polars/Python에서 수행하거나 UDF를 등록하십시오 (현재 지원 확인).

4. 중복 제거

  • 정확한 중복: 개수와 함께 제거하고, 남은 행의 소스 행 번호를 유지합니다.
  • 키별 중복: 먼저 진정한 반복인지 아니면 별개 이벤트인지 결정합니다 (동일한 송장 번호, 다른 금액은 충돌이지 중복이 아닙니다).
  • 잔존 행 선택은 결정적이어야 하며 명시되어야 합니다: ROW_NUMBER() OVER (PARTITION BY key ORDER BY updated_at DESC NULLS LAST, completeness DESC, source_row DESC) = 1 (DuckDB QUALIFY). ORDER BY는 항상 소스 행 번호와 같은 고유한 결정 분기 항목으로 끝나야 합니다. 그렇지 않으면 동점이 임의의 스캔 순서로 해결되기 때문입니다. polars에서는 sort(...) 다음에 unique(subset, keep="first", maintain_order=True)를 사용합니다.
  • 퍼지 중복 제거는 후보 생성기이며 자동 병합이 아닙니다: 저렴한 키 (정규화된 우편 번호, 처음 3글자, 연도)로 차단하고, 블록 내에서 점수를 매기고, 정확한 보조 필드가 일치하는 높은 임계값 이상만 자동 수락하고, 중간 대역은 사람에게 보냅니다. 임계값과 개수를 보고합니다.

5. 조정 감사

진실 공급원 = A, 파생 = B (예: 시스템 내보내기 대 OCR 문서). 추출이나 키가 잘못되었는지 확인하기 전에 "B가 잘못되었다"고 말하지 마십시오.

  1. 먼저 제어 합계. A와 B의 행 수와 모든 금액/수량 열의 합계, 그리고 고유 키 개수. 불일치는 누락된 행, 추가 행 또는 금액 차이를 예상해야 하는지 알려줍니다. 행이 다른데 합계가 같으면 상쇄 오류를 의미합니다. 계속 진행하십시오.
  2. 키 매칭. 양쪽에 동일한 정규화된 키를 구축합니다 (섹션 3). 먼저 정확히 일치시키고, 그 다음 명시적 단계에서 엄격성을 낮춥니다 (예: 키만, 그 다음 키와 날짜 기간). 각 일치 항목을 생성한 단계로 레이블을 지정하십시오. 레이블 없이 단계를 혼합하지 마십시오.
  3. 양방향 안티 조인. A에는 없지만 B에는 있는 항목 (파생에서 누락) 및 B에는 없지만 A에는 있는 항목 (파생에서 예상치 못한, 종종 OCR 키 오타 또는 중복). 둘 다 보고하십시오. 한 방향만 읽으면 오류의 절반을 숨깁니다. 행이 누락되었다고 말하기 전에 해당 키가 양쪽의 중복과 충돌하는지 확인하십시오 (다대다 조인은 합계를 부풀립니다).
  4. 매칭 쌍의 필드 비교. 동일한 정규화 후 필드별로 비교합니다. 금액 허용 오차: 하위 단위로 비교, abs(a - b) <= tol. 여기서 tol은 사전에 선언됩니다 (원장의 경우 0, 소스가 다르게 반올림하는 경우에만 라인당 1 하위 단위의 반올림 허용 오차, 소액에는 절대 백분율을 사용하지 않음). 날짜: 정확히 일치하거나 명시된 일 단위 기간. 텍스트: 정규화된 동등성, 그 다음 유사도 점수를 통과/실패가 아닌 점수로 보고합니다.
  5. 분류하고, 단순히 차이를 보지 마십시오. 각 예외에는 하나의 이유 코드가 있습니다: MISSING_IN_B, EXTRA_IN_B, DUP_KEY_A, DUP_KEY_B, AMOUNT_MISMATCH, FIELD_MISMATCH, UNPARSEABLE_A, UNPARSEABLE_B, AMBIGUOUS_MATCH. 파싱 불가능한 행은 예외이며 합계에서 조용히 제외되지 않습니다.
  6. 루프를 닫습니다. 최종 신원은 유지되어야 합니다: |A| = 일치 + B에서 누락 + A의 중복 초과 + A의 파싱 불가 (및 B의 등가). 균형이 맞지 않으면 감사가 완료되지 않은 것입니다.

단계, 안티 조인, 허용 오차 및 균형 검사를 위한 SQL 패턴은 references/reconciliation-recipes.md에 있습니다.

예외 보고서

도구 없이도 읽을 수 있는 행당 하나의 예외: reason_code, key, A 소스 파일 및 행 번호, B 소스 파일 및 행 번호 (스캔 문서의 경우 페이지), field, a_value, b_value, delta, suggested_action. 금액 영향 내림차순으로 정렬한 다음 이유별로 정렬합니다. 상단에 실행 요약을 넣습니다: 행 개수와 체크섬이 있는 입력, 개수가 있는 모든 정리 단계, 양쪽의 제어 합계, 균형 신원, 사용된 허용 오차. 기계용 CSV와 사람용 짧은 마크다운 또는 xlsx 보기를 작성하십시오. 수천 줄을 채팅에 덤프하지 말고 이유별로 개수를 요약하고 상위 몇 개를 보여주십시오.

보호 장치

  • 눈대중이 아닌 단언: 조인 후 행 수, 중복 제거 후 키 고유성, 금액에 float 열 없음.
  • 고유하지 않은 키에 대한 왼쪽 조인은 행을 곱합니다. 모든 조인 전후의 개수를 확인하십시오.
  • A를 덮어쓰지 마십시오. 진실 공급원에 대한 수정은 보고서에 나열된 사람의 결정입니다.
  • 데이터베이스용 비밀은 환경 변수나 명령줄이 아닌 /run/secrets/<name>에서 읽습니다.
  • 선언적 검사 (soda-core, great_expectations)는 규칙이 안정화되면 추가할 가치가 있습니다. 위의 프로필과 개수가 먼저입니다.

실제 사용에서 얻은 교훈은 references/gotchas.md에 축적됩니다.

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

관련 스킬