Перейти к основному содержимому

Контроль качества данных

Назначение и аудитория

Для разработчиков пайплайнов и аналитиков, которые принимают новую выгрузку бюджетных или смежных таблиц и должны быстро отловить дубли ключей, арифметические несостыковки и аномалии дат до построения отчётов.

Входные данные

  • Таблица факта — CSV/Parquet с явным первичным ключом анализа (например КБК + год + уровень бюджета).
  • Правила контракта — ожидаемые типы, диапазоны дат, обязательные поля; словарь измерений качества источника — измерения качества.
  • Справочник КБК на год — открытые данные Минфина и расшифровка КБК.
  • Иерархия сумм (если применимо) — таблица «родитель → дети» или код разрядности для проверки сублокальных правил.

Инструменты

  • Python 3csv, collections.Counter, простая арифметика; на больших объёмах — pandas (см. pandas: КБК).
  • SQLGROUP BY + HAVING COUNT(*) > 1 для дублей в СУБД.

Шаги

  1. Зафиксируйте первичный ключ строки отчёта и список обязательных полей.
  2. Проверьте дубликаты по ключу; при нахождении — остановите пайплайн или пометьте строки для ручного разбора.
  3. Проверьте ссылочную целостность — все КБК из факта есть в справочнике выбранного года (или соберите список «осиротевших» кодов).
  4. Проверьте иерархию сумм там, где она задана (дети не превышают родителя, сумма детей сходится с родителем в допуске).
  5. Сформируйте отчёт 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).
  • Не путайте технический дубль строки и легитимные несколько строк с разными уровнями или источниками финансирования.

Связанные страницы