Контроль качества данных
Назначение и аудитория
Для разработчиков пайплайнов и аналитиков, которые принимают новую выгрузку бюджетных или смежных таблиц и должны быстро отловить дубли ключей, арифметические несостыковки и аномалии дат до построения отчётов.
Входные данные
- Таблица факта — CSV/Parquet с явным первичным ключом анализа (например КБК + год + уровень бюджета).
- Правила контракта — ожидаемые типы, диапазоны дат, обязательные поля; словарь измерений качества источника — измерения качества.
- Справочник КБК на год — открытые данные Минфина и расшифровка КБК.
- Иерархия сумм (если применимо) — таблица «родитель → дети» или код разрядности для проверки сублокальных правил.
Инструменты
- Python 3 —
csv,collections.Counter, простая арифметика; на больших объёмах —pandas(см. pandas: КБК). - SQL —
GROUP BY+HAVING COUNT(*) > 1для дублей в СУБД.
Шаги
- Зафиксируйте первичный ключ строки отчёта и список обязательных полей.
- Проверьте дубликаты по ключу; при нахождении — остановите пайплайн или пометьте строки для ручного разбора.
- Проверьте ссылочную целостность — все КБК из факта есть в справочнике выбранного года (или соберите список «осиротевших» кодов).
- Проверьте иерархию сумм там, где она задана (дети не превышают родителя, сумма детей сходится с родителем в допуске).
- Сформируйте отчёт QC — счётчики нарушений, доля строк с предупреждениями, дата выгрузки.
Воспроизводимый пример
Учебный CSV: дубль по паре (КБК, год) и несходимость «родитель vs сумма детей».
import csv
import io
from collections import Counter
CSV_TEXT = """kbk,year,level,amount_mln
12345678901234567890,2024,federal,100
12345678901234567890,2024,federal,100
12345678901234567890,2024,regional,40
99999999999999999999,2024,federal,5
"""
rows = list(csv.DictReader(io.StringIO(CSV_TEXT)))
keys = [(r["kbk"], r["year"]) for r in rows]
dup_keys = [k for k, c in Counter(keys).items() if c > 1]
print("Дубли по (КБК, год):", dup_keys)
by_kbk_year = {}
for r in rows:
k = (r["kbk"], r["year"])
by_kbk_year[k] = by_kbk_year.get(k, 0) + float(r["amount_mln"])
# Учебное правило: для одного КБК ожидаем сумму уровней = 140 при отсутствии дубля
# Здесь дубль завышает контрольную сумму — детектор срабатывает
if dup_keys:
print("Итог по проблемному ключу (с дублем):", by_kbk_year[dup_keys[0]])
Ожидаемо: Дубли по (КБК, год): содержит ('12345678901234567890', '2024'), итог по этому ключу 240.0 (два раза по 100 + 40), что сигнализирует о необходимости дедупликации перед проверкой иерархии.
Проверка результата
- Скрипт находит ровно один дублирующийся ключ в учебных данных.
- После удаления дубля по одной из строк сумма по уровням для
123…становится 140.0 (100 + 40) — тогда можно сравнивать с «родителем» в отдельной таблице. - На реальных данных — нулевой или заранее оговорённый допуск на «осиротевшие» КБК после джойна со справочником.
Ограничения и типовые ошибки
- QC не заменяет аудит смысла — корректные суммы при неверной интерпретации КБК всё равно вводят в заблуждение.
- Ведущие нули в КБК — храните как строки, иначе Excel и JSON «съедят» разряды.
- Разные версии одной выгрузки в один день — сравнивайте по хэшу файла или метаданным паспорта набора (budget.gov.ru).
- Не путайте технический дубль строки и легитимные несколько строк с разными уровнями или источниками финансирования.