| name | scan-and-profile |
| description | Profile and scan datasets with Pointblank before writing validation rules. Covers DataScan for column-level statistics, Schema inference with schema_from_tbl(), missing values analysis with missing_vals_tbl(), and table previewing. Use when exploring a new dataset or understanding data distributions before validation.
|
| license | MIT |
| compatibility | Requires Python >=3.10, pointblank installed. |
| metadata | {"author":"rich-iannone","version":"1.0","tags":["data-profiling","data-scan","schema","data-exploration","missing-values"]} |
Scan and Profile
Skill for profiling datasets before writing validation rules.
Understanding your data's shape, types, distributions, and
missingness patterns helps you write targeted, effective
validation plans.
Quick start
import pointblank as pb
scan = pb.DataScan(data=df, tbl_name="orders")
scan.get_tabular_report()
Skill directory structure
skills/scan-and-profile/
+-- SKILL.md <- This file
+-- references/
+-- datascan-reference.md <- DataScan details and output
+-- schema-inference.md <- Schema inference and construction
When to use what
| I want to... | Use |
|---|
| Get a full column-level profile | DataScan |
| See column types and basic stats | DataScan.get_tabular_report() |
| Export profile as JSON | DataScan.to_json() |
| Infer a schema from data | schema_from_tbl() |
| Infer a schema with constraints | Schema.from_table() |
| See a quick preview of the table | preview() |
| Analyze missing values | missing_vals_tbl() |
| Get row/column counts | get_row_count(), get_column_count() |
Core concepts
DataScan
DataScan produces a comprehensive profile of every column in a
dataset:
scan = pb.DataScan(data=df, tbl_name="monthly_sales")
scan.get_tabular_report()
scan.get_tabular_report(show_sample_data=True)
scan.summary_data
json_str = scan.to_json()
scan.save_to_json("profile_output.json")
The report includes per-column:
- Data type
- Count of non-null values
- Missingness (count and percentage)
- Distinct value count
- Negative / zero / positive value counts (numeric)
- Descriptive statistics (mean, median, std, min, max)
- Quantiles (Q1, Q3, IQR)
Shortcut: col_summary_tbl
For a quick column summary without creating a DataScan object:
pb.col_summary_tbl(data=df, tbl_name="orders")
Table preview
Quick visual preview of the first and last rows:
pb.preview(data=df, n_head=5, n_tail=5)
pb.preview(
data=df,
columns_subset=["id", "name", "amount"],
n_head=10,
n_tail=3,
limit=50,
show_row_numbers=True,
max_col_width=250,
)
Missing values analysis
Dedicated analysis of missingness patterns:
pb.missing_vals_tbl(data=df)
pb.missing_vals_tbl(data=df, as_heatmap=True)
missing_specs = {
"measurement": pb.MissingSpec(
reasons={-999: "not collected", -1: "redacted"},
),
"notes": pb.MissingSpec(
reasons={"N/A": "not applicable"},
),
}
pb.missing_vals_tbl(data=df, missing=missing_specs)
Schema inference
Infer a schema from an existing table:
schema = pb.schema_from_tbl(df)
print(schema.get_column_list())
print(schema.get_dtype_list())
schema = pb.Schema.from_table(
df,
infer_constraints=True,
categorical_threshold=20,
detect_presets=True,
sample_size=None,
)
Constructing schemas manually
schema = pb.Schema(id="Int64", name="String", amount="Float64")
schema = pb.Schema({"id": "Int64", "name": "String"})
schema = pb.Schema([("id", "Int64"), ("name", "String")])
schema = pb.Schema(["id", "name", "amount"])
Schema inspection
schema.get_column_list()
schema.get_dtype_list()
Quick counts
pb.get_row_count(df)
pb.get_column_count(df)
Workflows
Profiling a new dataset
- Load or connect to the data.
- Run
pb.preview(data) for a quick look.
- Run
pb.DataScan(data=df).get_tabular_report() for full stats.
- Run
pb.missing_vals_tbl(data=df) to understand missingness.
- Infer a schema:
schema = pb.schema_from_tbl(df).
- Use the profile to inform validation rules.
From profile to validation plan
- Profile the data with
DataScan.
- Note columns with high missingness -- add
col_pct_null checks.
- Note columns with few distinct values -- add
col_vals_in_set.
- Note numeric ranges -- add
col_vals_between checks.
- Infer schema and use in
col_schema_match.
- Build the validation plan with the
write-validation skill.
Comparing profiles over time
scan_today = pb.DataScan(data=today_df)
scan_yesterday = pb.DataScan(data=yesterday_df)
scan_today.save_to_json("profile_today.json")
scan_yesterday.save_to_json("profile_yesterday.json")
Gotchas
- DataScan reads the full table. For large datasets, consider
sampling first.
- Schema type names are backend-specific. Polars uses
"Int64",
Pandas uses "int64". Use schema_from_tbl() to get the right
names automatically.
schema_from_tbl infers from current data. If the data has
unexpected types (e.g., string column with numbers), the inferred
schema reflects that.
missing_vals_tbl only shows null by default. Pass
MissingSpec definitions to include sentinel values.
preview() returns a GT table object. In notebooks it renders
automatically; in scripts, you may need to display it.
Related skills
| Skill | When to use it |
|---|
| pointblank | Full Validate workflow overview |
| write-validation | Build validation plans from profile insights |
| generate-data | Create synthetic data matching a schema |