关于 data-profiling
data-profiling 是用于探索陌生数据集的技能,可评估其结构、质量、新鲜度和规律。它为数据分析人员提供表与列检查、关系发现、异常识别和结果记录方法。
主要功能
- 01盘点表与列
- 02列角色分类
- 03质量与新鲜度检查
- 04发现数据关系
- 05分析分布与时间规律
- 06指导数据集文档编写
适用场景
- 01检查陌生数仓表
- 02发现缺失、不一致或异常值
- 03核查数据新鲜度与时间序列缺口
- 04记录模式结构与数据血缘
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ okou-ai/ okou-skills --skill data-profiling安装后在 Claude Code 中输入/data-profiling确认已加载。
详细介绍
结构探查
表级清单
每次接触新数据集时,都先回答以下问题:
- 总行数和列数是多少?
- 每行代表什么(粒度)?
- 哪一列或哪些列可以唯一标识一行?
- 最近一次加载数据是什么时候?
- 数据集中的最早日期是什么?
按角色分类列
将每列归入以下类别之一:
- 键:主键、外键、实体标识符
- 属性:用于分组或筛选的分类字段(region、status、plan_type)
- 度量:用于聚合的数值字段(revenue、duration、score)
- 时间戳:日期或日期时间字段(created_at、processed_on、event_date)
- 自由文本:非结构化字符串(描述、评论、名称)
- 标志:二元真假指示值
- 嵌套:JSON 数据块、数组或嵌入式结构
列级检查
通用检查(适用于所有列类型)
- 空值数量和空值百分比
- 不同值的数量和基数比(不同值数量 / 总行数)
- 出现频率最高的 5-10 个值及其出现次数
- 出现频率最低的 5 个值(有助于发现异常)
数值度量
Minimum, maximum, mean, median
Standard deviation
Percentile ladder: p1, p5, p25, p75, p95, p99
Count of zeros
Count of negatives (flag if unexpected)
文本和分类字段
Shortest length, longest length, average length
Count of empty strings
Format regularity (do values follow a consistent pattern?)
Case consistency (uniform upper, uniform lower, or mixed?)
Count of values with leading or trailing whitespace
日期和时间戳字段
Earliest date, latest date
Count of nulls
Count of future dates (flag if the domain forbids them)
Distribution across months or weeks
Gaps in expected daily/weekly cadence
布尔字段
True count, false count, null count
True proportion
发现关系
逐列检查后,寻找列之间的联系:
- 外键候选项:值可能引用其他表的 ID 列
- 层级维度:自然嵌套的列(国家 > 地区 > 城市)
- 相关度量:趋势一致的数值列
- 计算列:看起来由同一表中的其他列推导而来的字段
- 重复信息:内容相同或近乎相同的列
评估数据质量
完整性评级
为每列分配一个等级:
- 完整(>99% 有值):无需处理
- 基本完整(95-99%):调查缺失值
- 存在缺口(80-95%):确定缺口是否具有规律性,以及该列是否仍可使用
- 稀疏(<80%):若不进行填补或补充数据,可能无法使用
一致性检查
扫描以下问题:
- 值规范化失败:同一概念有多种写法(“USA”、“US”、“United States”、“us”)
- 类型不匹配:数值以文本形式存储,日期格式不一致
- 引用失效:外键值找不到匹配的父记录
- 规则违规:数量为负数、结束日期早于开始日期、百分比不在 0-100 范围内
- 跨列矛盾:status = 'shipped',但 ship_date 为空
准确性警示信号
以下模式可能表明数据不可靠:
- 哨兵值:0、-1、999999、“N/A”、“TBD”、“test”、“xxx”
- 占比异常高的默认值:某个值出现频率远高于预期
- 过时记录:在活跃系统中,updated_at 列显示近期没有任何活动
- 物理上不可能的值:年龄超过 150 岁、日期在未来数十年、持续时间为负数
- 舍入痕迹:数值异常集中在 5 或 10 的倍数上(表明数据是估算得出的)
新鲜度评估
- 最新行的时间戳是什么?
- 此表应多久刷新一次?
- 事件发生到数据进入数据仓库之间是否存在可测量的延迟?
- 时间序列中是否缺少某些日期或小时?
识别模式
分布形态
对数值列进行分析时,判断其分布形态:
- 钟形分布:均值与中位数几乎相等;两侧尾部对称
- 右偏分布:右侧长尾,且有少数极大值(收入、会话时长通常属于这种情况)
- 左偏分布:左侧长尾,且有少数极小值(较少见)
- 双峰分布:有两个明显峰值(可能表明合并了两个总体)
- 幂律分布:少数极大值占主导;许多值接近零(用户参与度指标)
- 均匀分布:整个范围内大致平坦(通常为合成或随机生成的数据)
基于时间的模式
对于任何时间数据,请调查:
- 趋势:持续上升或下降
- 季节性:周期性重复的变化——每周、每月、每季度、每年
- 工作日效应:工作日与周末之间的系统性差异
- 节假日影响:已知节假日前后的峰值或低谷
- 水平突变:基线突然且持续地变化
- 孤立异常:偏离现有模式的单个数据点
细分发现
通过以下方式发现自然分组:
- 找出包含 3 到 20 个不同值的类别列
- 比较各细分值的指标分布
- 标出行为与整体明显不同的细分
- 检查表面上的细分是否包含有意义的子细分
相关性扫描
针对数值列:
- 构建两两相关性矩阵
- 标出强相关性(|r| > 0.7)
- 请记住,相关性并不能证明因果关系——明确注明这一点
- 探查 Pearson r 可能无法发现的非线性关系(二次、对数)
记录发现
数据集摘要模板
## Table: [schema.table_name]
**Purpose**: [What this table captures]
**Grain**: [One row per...]
**Primary Key**: [column(s)]
**Approximate Rows**: [count, as of date]
**Refresh Cadence**: [real-time / hourly / daily / weekly]
**Responsible Team**: [owner]
### Important Columns
| Column | Type | Meaning | Sample Values | Notes |
|--------|------|---------|---------------|-------|
| user_id | STRING | Unique user handle | "usr_abc123" | References users.id |
| event_type | STRING | Action category | "click", "view", "purchase" | 15 distinct values |
| revenue | DECIMAL | USD transaction amount | 29.99, 149.00 | Null for non-purchases |
| created_at | TIMESTAMP | Event occurrence time | 2024-01-15 14:23:01 | Partition column |
### Join Paths
- Links to `users` via `user_id`
- Links to `products` via `product_id`
- Parent of `event_details` (one-to-many on event_id)
### Known Caveats
- [Document any quality issues]
- [Note analytical gotchas]
### Typical Query Use Cases
- [List common analytical patterns against this table]
架构发现查询
直接查询数据仓库时,请使用以下模式:
-- Enumerate tables in a schema (PostgreSQL)
SELECT table_name, table_type
FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY table_name;
-- Inspect column metadata (PostgreSQL)
SELECT column_name, data_type, is_nullable, column_default
FROM information_schema.columns
WHERE table_name = 'target_table'
ORDER BY ordinal_position;
-- Rank tables by storage footprint (PostgreSQL)
SELECT relname, pg_size_pretty(pg_total_relation_size(relid))
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC;
-- Row count per table (general approach)
-- Execute individually: SELECT COUNT(*) FROM table_name
追溯数据血缘
在不熟悉的数据仓库中进行探索时:
- 从消费层开始——找出为报告和仪表板提供数据的表
- 沿依赖关系向上追溯:哪些数据为这些表提供输入?
- 梳理原始数据层/暂存层/数据集市架构
- 追踪数据转换发生的位置,以及数据在何处被丰富、筛选或汇总
- 记录与外部数据源进行数据联接的位置
评论
支持 Markdown