본문으로 건너뛰기
cccskills
무료GitHub에 공개

eda-and-data-profiling

Use when you meet a new dataset, table, file or source, before building features or a model on it, or when a number looks wrong — profile grain, keys, nulls, cardinality, time coverage and target balance, and persist what you learn as code

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md5.5 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

EDA and Data Profiling

Overview

Exploration answers "what is actually in this data?" before anything is built on it. In this role exploration has a deliverable: the facts you learn become a schema, a test or a documented assumption in the repository — not a notebook cell nobody re-runs.

Core principle: every surprise you find in EDA ends up as a check that would catch it next time (data-validation-contracts) or a written assumption in your closing message.

1. Structure first

Answer these before looking at any distribution:

  • Grain: one row is one what? (an order, an order line, a customer-day)
  • Key: which column(s) identify a row — and are they actually unique?
  • Size and span: row count, earliest and latest timestamp, any missing days.
  • Freshness: when was it last updated; is the latest period complete?
  • Column roles: identifier, dimension, metric, timestamp, free text, boolean, nested.
def assert_grain(df: pd.DataFrame, key: list[str]) -> None:
    dupes = df.duplicated(subset=key, keep=False)
    if dupes.any():
        raise ValueError(f"{int(dupes.sum())} rows share a {key} key, e.g. {df.loc[dupes, key].head(3).to_dict('records')}")

2. Profile every column

Column kindLook at
Allnull rate, distinct count, cardinality ratio, top and bottom values
Numericmin, p1, p25, median, mean, p75, p99, max; zeros; negatives where impossible
String / categoryempty strings, whitespace, case variants ("US", "us", "USA"), unexpected categories
Timestampmin/max, future dates, gaps per day/week, timezone (naive vs aware)
Targetclass balance or distribution, by time period

Fast paths:

duckdb.sql("SUMMARIZE SELECT * FROM 'data/events/*.parquet'").df()
def profile(df: pd.DataFrame) -> pd.DataFrame:
    return pd.DataFrame({
        "dtype": df.dtypes.astype(str),
        "null_rate": df.isna().mean(),
        "n_unique": df.nunique(dropna=True),
        "example": df.apply(lambda s: s.dropna().iloc[0] if s.notna().any() else None),
    })

Profile on the full data or a documented sample — a 1,000-row head of a file sorted by date tells you about one day.

3. Quality signals that need a decision

SignalLikely causeDecide
Null rate > 5% in a key columnupstream gap, late arrival, optional fieldimpute in the pipeline, exclude with a reason, or flag
Placeholder values (0, -1, 999999, "N/A", "test", 1970-01-01)defaults standing in for missingconvert to NA at ingestion, with a test
One value with suspicious frequencya default or a backfillconfirm with the source owner, or note it
ID with far fewer distinct values than rows expectedwrong join key or truncated extractstop and trace before modelling
Status says done but the done-timestamp is nullcross-column inconsistencya schema check across columns
Values all ending in 0 or 5estimates, not measurementsnote it as a precision limit
Distribution shift between old and recent monthsdrift, a tracking change, a definition changeevaluate on the recent period separately

Do not silently drop outliers: decide whether each group is an error (fix or remove, with a count), a genuine extreme (keep, use robust statistics) or another population (segment it).

4. Relationships and joins

  • For every join you plan, measure coverage: what share of left rows find a match, and how many matches each gets.
  • Check foreign keys that point at nothing (referential gaps) and keys that appear many times on the side you expected to be unique.
  • Look for derived or redundant columns (a total next to its parts) and columns that are suspiciously predictive of the target — a single-feature ROC-AUC near 1.0 is usually leakage.
merged = events.merge(users, on="user_id", how="left", validate="many_to_one", indicator=True)
unmatched = (merged["_merge"] == "left_only").mean()

5. Persist what you learned

  • A schema at the ingestion boundary encoding the facts: key uniqueness, allowed ranges, allowed categories, nullable columns (data-validation-contracts).
  • A test for every cleaning rule EDA motivated ("placeholder -1 in age becomes NA").
  • Plots and long profiles go to /tmp/tt-<task key>/ while you work; commit them only where the repository keeps reports.
  • Your closing message states the key numbers: rows, span, null rates that mattered, what you excluded and how many rows that was.

Common Mistakes

  • Profiling a head or a non-random sample and generalising.
  • Assuming a key is unique because its name ends in _id.
  • Treating the latest, incomplete day or month as a real drop.
  • Fixing a quality issue in a notebook and never in the pipeline.
  • Comparing timestamps from sources in different timezones.

Red Flags

  • Row count changes after a join you believed was one-to-one.
  • A target rate that jumps on a specific date — check for a definition or tracking change before modelling it.
  • Exact round totals or 0%/100% rates — usually a filter or a default value.
  • "The data looks fine" without a single number to show for it.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

makifbaysal/tasktrooper1172026년 10월 21일 업데이트

Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

makifbaysal/tasktrooper1172026년 10월 21일 업데이트

Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

makifbaysal/tasktrooper1172026년 10월 21일 업데이트

Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

makifbaysal/tasktrooper1172026년 10월 21일 업데이트

How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

makifbaysal/tasktrooper1172026년 10월 21일 업데이트

Use when the repository keeps its alerting in code, or a person asks for alerts outside TaskTrooper - PrometheusRule YAML, a Cloud Monitoring alert policy in Terraform, a Datadog monitor, each routed to TaskTrooper's alert ingest URL so it opens an incident here

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

makifbaysal/tasktrooper1172026년 10월 21일 업데이트

makifbaysal의 스킬 모두 보기

이 스킬의 문제 신고