Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Finance Flow

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

Проект вырос из реальной бытовой задачи по учёту семейных финансов и со временем превратился в переиспользуемый пайплайн обработки полуструктурированных финансовых данных.

Зачем этот проект

  • Решает прикладную задачу: собирает операции из разных банков и форматов выписок в одну чистую таблицу.
  • Работает с “грязным” реальным вводом: PDF-выписки, CSV-экспорты, неоднотипные описания операций и различающиеся банковские форматы.
  • Показывает полный цикл работы с данными: парсинг, очистка, обогащение по правилам и выгрузка в отчёт.

Возможности

  • Парсинг выписок из:
    • PDF по карте Сбера
    • PDF по сберегательным счетам и вкладам Сбера
    • CSV-экспортов Т-Банка
    • PDF-выписок Ozon Банка
  • Определение направления и типа транзакции
  • Нормализация категорий по YAML-правилам
  • Фильтрация внутренних переводов между своими счетами
  • Сохранение итогового датасета в CSV
  • Готовый демо-набор на вымышленных данных (demo_data/)

Стек

  • Python
  • pandas
  • pdfplumber
  • PyYAML
  • Tableau

Схема пайплайна

flowchart LR
    A["Банковские выписки (PDF / CSV)"] --> B["Слой парсинга (кастомные парсеры)"]
    B --> C["Нормализованная таблица транзакций"]
    C --> D["Определение типа (доход / расход / внутренний / возврат)"]
    D --> E["Уточнение категорий (YAML-правила)"]
    E --> F["Финальный подготовленный датасет"]
    F --> G["CSV с результатом (<набор>/output/)"]
Loading

Структура репозитория

.
├── configs/
│   ├── types.sample.yaml       # демо-правила типов под demo_data/
│   └── categories.sample.yaml  # демо-правила категорий под demo_data/
├── parsers/
│   ├── sber.py              # парсеры PDF-выписок Сбера
│   ├── tbank.py             # парсер CSV из Т-Банка
│   ├── ozon.py              # парсер PDF-выписок Ozon
│   └── utils.py             # regex-шаблоны, нормализация текста, валидация схемы
├── pipeline/
│   ├── parsing.py           # обход папки и маршрутизация файлов
│   ├── typification.py      # определение типа операции и возвратов
│   ├── categorization.py    # присвоение категорий по правилам
│   ├── coverage.py          # проверка покрытия и заготовки правил
│   ├── logger.py            # настройка логирования
│   └── utils.py             # загрузка YAML-конфигов
├── demo_data/               # вымышленный набор для демо
│   ├── input/               # игрушечные выписки
│   └── output/              # результат демо-прогона
├── data/                    # реальные данные (в .gitignore): input/ + output/
├── run_pipeline.py          # CLI-точка входа
└── requirements.txt

Реальные configs/types.yaml / configs/categories.yaml содержат личные правила и в git не попадают.

Как работает проект

1. Парсинг

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

Основные точки входа:

2. Нормализация и обогащение

После парсинга все операции приводятся к единой схеме:

  • source
  • date
  • direction
  • raw_amount
  • raw_category
  • raw_description

Дальше пайплайн:

  • определяет тип операции (доход, расход, внутренний, возврат)
  • уточняет категории на основе YAML-правил
  • удаляет переводы между собственными счетами

Ключевая логика:

3. Проверка покрытия и доразметка

Правила покрывают не все транзакции. Категория при непокрытии берётся из сырой банковской (raw_category заполнена всегда), а вот подкатегория без правила остаётся пустой — при добавлении новых выписок копятся недоразмеченные операции. Поэтому после категоризации пайплайн проверяет покрытие по подкатегориям и логирует метрику ([COVERAGE] .../... (%)).

Если покрытие неполное, пайплайн:

  • пишет output/suggested_rules.yaml — готовые YAML-заготовки правил (по одному широкому правилу на банковскую категорию), под вставку в categories.yaml;
  • при ручном запуске в терминале — приостанавливается и ждёт: правишь правила, жмёшь Enter → пересчёт только категоризации (без повторного парсинга PDF, ~1с), новая метрика; цикл до 100% или до q;
  • при автоматическом запуске (не терминал) — интерактив пропускается, недоразмеченные получают подкатегорию «Прочее», прогон идёт дальше.

Итог всегда полный: непокрытые подкатегории заполняются значением «Прочее». Логика — pipeline/coverage.py.

4. Выгрузка

Финальный очищенный датасет сохраняется в CSV рядом с входными данными — в <data_набор>/output/transactions.csv (перезаписывается при каждом прогоне). Дальше его удобно подхватывать в BI-инструментах.

Дашборд

Итоговый датасет визуализируется в Tableau. Дашборд собран на вымышленном наборе demo_data/.

🔗 Интерактивная версия: Finance Flow на Tableau Public

Дашборд «Мои финансы» — обзор на демо-данных

Интерактив — фильтры по году/месяцу и drill-down по категориям:

Фильтрация по месяцу:

Фильтр по месяцу

Drill-down: клик по категории фильтрует весь дашборд:

Drill-down по категории

Детализация по выбранной категории:

Детализация по категории

Сам файл .twbx в репозиторий не коммитится (содержит экстракт данных) — он остаётся локально, а в портфолио ведёт ссылка на Tableau Public.

Локальный запуск

1. Создать окружение

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

2. Подготовить входные данные

Положите выписки в папку data/input/.

Сейчас поддерживаются такие шаблоны имён:

  • sber*.pdf
  • tbank*.csv
  • ozon*.pdf

3. Подготовить конфиги

Реальные configs/types.yaml и configs/categories.yaml лежат вне git. В качестве отправной точки возьмите демо-конфиги и отредактируйте их под свои банки и категории.

А для прогона на демо-данных конфиги уже готовы — configs/types.sample.yaml и configs/categories.sample.yaml, копировать ничего не нужно.

4. Запустить пайплайн

Запуск из командной строки:

python run_pipeline.py

По умолчанию результат сохранится рядом с входными данными — в data/output/transactions.csv и будет перезаписываться при каждом прогоне. Каждый датасет самодостаточен: <папка>/input/ для выписок, <папка>/output/ для результата.

Готовый пример на вымышленных данных лежит в demo_data/:

python run_pipeline.py --data-dir demo_data \
  --types-config configs/types.sample.yaml \
  --categories-config configs/categories.sample.yaml

Что показывает этот проект

  • Разработку кастомных парсеров для полуструктурированных документов
  • Проектирование слоя нормализации для неоднородных источников данных
  • Правила категоризации и контроля качества данных
  • Автоматизацию рутинной личной аналитики
  • Интеграцию Python-пайплайна с инструментами отчётности

Приватность

Репозиторий подготовлен для публичного GitHub-портфолио. Реальные банковские выписки, Excel-файлы и ключи доступа не должны попадать в git. Папка data/ (входные данные и выгрузки) и личные configs/*.yaml целиком исключены через .gitignore; в git попадают только вымышленный набор demo_data/, и демо-конфиги configs/*.sample.yaml.

Contributors

Languages