Senior Data Analyst
779 subscribers
326 photos
8 videos
152 links
Data Analyst 360°
SQL, Python, ML, GPT, матстат и визуализация
BI, A/B, метрики, продуктовая аналитика
Для junior → middle → senior

Если хотите поддержать автора — здесь можно это сделать https://teletype.in/@seniorru

По вопросам: @seniorru
Download Telegram
🛠 Как читать EXPLAIN и ускорять SQL-запросы
Часть 2: практичный гайд, без теории ради теории

▫️Что делает EXPLAIN?
Показывает, как именно PostgreSQL будет исполнять запрос:
что читает, в каком порядке, как соединяет таблицы, сколько строк ждёт и сколько реально вернул.

EXPLAIN ANALYZE — то, что используем в проде:
показывает фактическое выполнение:
•  строки, прошедшие через каждый шаг
•  время выполнения
•  количество повторов (loops)
•  сколько реально читали с диска

▫️Как читать план:
Тип операции:
Seq Scan — чтение всей таблицы. Норм на маленьких, боль на больших
Index Scan — идеал при точном фильтре
Bitmap Index Scan — хорош при нескольких фильтрах
Nested Loop — хорошо при малом внешнем наборе
Hash Join — рулит при JOIN ON a = b и достаточно памяти
Sort — потенциально опасен, если не влезает в память
Читай снизу вверх: от таблиц к джойнам и агрегациям

Rows / Loops / Time
actual time=0.05..0.09 rows=1 loops=1

•  rows — сколько вернул
•  loops — сколько раз вызвали
•  если expected ≠ actual — планировщик ошибается → неоптимальный план

Total cost
Не время, а "оценка тяжести" запроса.
Используй для сравнения разных планов.

BUFFERS
Добавь EXPLAIN (ANALYZE, BUFFERS)
•  read → реально лезли на диск
•  shared hit → всё в кеше
•  если много read → нет индекса, не влезло в память

▫️Как реально ускорять запросы ?

1. Индексы по WHERE, JOIN, GROUP BY
CREATE INDEX idx_orders_user_date ON orders(user_id, order_date);

Порядок колонок важен. Не ставь индексы "на всякий".

2. Делим фильтрацию и агрегацию
Вместо:
SELECT user_id, COUNT(*) FROM orders WHERE ... GROUP BY user_id;

Так:
WITH filtered AS (
SELECT user_id FROM orders WHERE ...
)
SELECT user_id, COUNT(*) FROM filtered GROUP BY user_id;


3. Следи за LEFT JOIN
Фильтр по правой таблице? Лучше вынеси в подзапрос.
PostgreSQL может выбрать ужасный план.
•  pg_stat_statements — какие запросы дорогие
•  pg_stat_user_indexes — какие индексы реально нужны
•  auto_explain — лог запросов с плохими планами
•  track_io_timing — кто грузит диск

▫️Типичные ошибки:
• Seq Scan по большой таблице — нет фильтра или индекса
• JOIN по неиндексированному полю → Hash Join на всё
• Группировка по "широкой" колонке → сортировка в памяти
• Подзапрос без LIMIT — тянет всё
• ORDER BY без индекса — внешняя сортировка, тормоза

▫️Как нужно оптимизировать
•  EXPLAIN ANALYZE — найти узкое место
•  Сформулировать гипотезу (индекс, переписать логику)
•  Внести минимальные изменения
•  Проверить новый план
•  Повторять, пока не будет норм

Важно не просто “сделать быстрее”, а понимать — почему стало быстрее.


💥 Как тебе ?

🔥 — узнал(а) что-то новое
🤝 — темы хорошо знакомы

💸 Поддержать канал
👉 Senior Data Analyst | #sql
🔥6🤝3
Так можно визуализировать разницу между группами — понятно, гибко и без BI.

Bar-график с доверительными интервалами — для простого сравнения средних.
Boxplot со swarm — чтобы увидеть выбросы и структуру распределения.
KDE — когда хочется заглянуть в форму данных: есть ли смещение, мода, хвосты.

Чистый код, никаких кликов, полная автоматизация. Подходит, если ты работаешь в Jupyter, хочешь встроить график в пайплайн или просто устал от BI-интерфейсов.

💸 Поддержать канал
👉 Senior Data Analyst | #Python
🔥5👌2
🧠 Бывает, нужно не просто показать «где среднее больше», а понять —
есть ли реальная разница между группами,
и насколько она вообще значимая.

Хочется сделать это:
— быстро
— без BI
— и без ощущения, что ты в Excel 2007

Вот три способа, которые работают.
Особенно если ты работаешь в Python, сидишь в Jupyter или просто не хочешь лезть в дашборды ради одной простой мысли: «а группы-то разные?»

1️⃣ Bar-график с доверительными интервалами

Что показывает:
— среднее значение по каждой группе
— вертикальные полоски — это 95% доверительные интервалы

Зачем это нужно:
Если интервалы не пересекаются — можно аккуратно говорить,
что между группами есть статистическая разница.

Почему работает:
— среднее понятно всем, даже продуктам
— CI выглядит серьёзно и просто одновременно
— идеально, когда надо вставить в презентацию или закинуть в чат

Минусы:
— если распределение несимметричное, картина может быть кривой
— на маленьких выборках CI становятся как шпаги — длинные и бесполезные
— 95% — это не истина, просто привычка

Когда использовать:
Когда надо быстро объяснить:
«вот здесь значение выше, и это не просто флуктуация, а, кажется, что-то реальное»

2️⃣ Boxplot + swarmplot
Классика с лицом. Видно всё, что происходит внутри.

Что показывает:
— медиану
— интерквартильный размах
— выбросы (boxplot)
— и каждую точку отдельно (swarm)

Зачем:
Такой график сразу показывает:
— где плотность
— где шум
— и где твоя метрика ведёт себя странно

Почему хорошо:
— boxplot привычен
— swarm даёт ощущение, что ты «видишь сырые данные»
— в паре они дают и форму, и структуру, и реальность

Минусы:
— на больших объёмах swarm превращается в хаос
— выбросы могут отвлекать, а могут быть важны
— визуально может быть перегружено, если неаккуратно оформить

Когда использовать:
Перед t-тестом, Mann-Whitney, или когда просто хочется понять:
✔️ всё ли ок внутри группы
✔️ не разваливается ли она на две разные
✔️ есть ли странности, которые лучше бы не игнорировать

3️⃣ KDE (плотности распределения)

Что показывает:
— гладкие кривые плотности по каждой группе
— можно сравнивать форму, центр, хвосты, моды

Зачем:
— идеально видно, насколько сильно и как именно отличаются группы
— симметрия, мультимодальность, сдвиги — всё читается с графика

Почему лучше, чем гистограмма:
— никакого биннинга
— линии — это не только красиво, но и удобно для сравнения
— если сделать аккуратно — график говорит сам за себя

Минусы:
— bandwidth (параметр сглаживания) решает всё: можно сгладить всё важное или показать только шум
— не работает с категориальными данными
— нормализация (common_norm) влияет на восприятие, с этим надо быть аккуратным

Когда использовать:
Для сравнения распределений:
✔️ до/после изменений в продукте
✔️поведение по сегментам
✔️время отклика, длина сессии, стоимость заказа

▪️Зачем вообще визуализировать в коде, а не в BI?

— полная свобода: цвета, подписи, стиль, порядок
— удобно встроить в пайплайн, ноутбук, автотест или даже Airflow
— не надо ждать, пока BI перерисует график
— можно расширять под задачу: добавить тесты, аннотации, пояснения, бренд

И главное:
ты не ограничен интерфейсом — только своей логикой и фантазией

▪️Итог

BI — это красиво. Но часто громоздко.
Если тебе нужен контроль, гибкость и повторяемость, визуализация через код — твой лучший друг.
Проверяешь гипотезу.
Объясняешь данные.
Делаешь так, чтобы все поняли — вот здесь действительно что-то изменилось.

💸 Поддержать канал
👉 Senior Data Analyst | #Python
🔥71
🧠 Python для аналитиков: циклы без лишнего кода
for, while и идиоматичный Python — вживую, по делу

Это вторая серия модуля 3, и она про то, как писать циклы так, чтобы не стыдно было.

for — от списков до словарей, с zip() и enumerate()
while — когда не знаешь, сколько раз, но точно надо
генераторы, any, all, sorted — чтоб писать красиво
Задачи:
— фильтрация CSV,
— отчёт по продажам,
— имитация банкомата (с ошибками, как в жизни)

После этой серии ты забудешь, как выглядят "петли ада" и начнёшь писать коротко, понятно и без лишних if'ов.

💸 Поддержать канал, сказать «ну кайф» и скачать серию можно тут
❤️ И да, поставь реакцию за старание

👉 Senior Data Analyst #python #модуль_03 #серия_02
57
⚠️ Три SQL-ловушки даже для опытных

1. LEFT JOIN, который стал INNER
Думал, берёшь всех пользователей, даже без заказов? А фильтр по правой таблице в WHERE выкинул NULL-ы — и всё, отчёт «похудел».
Если нужен INNER — пиши его явно.

2. DISTINCT как пластырь
Дубликаты? DISTINCT скроет их, но не исправит причину — кривые ключи или «многие-ко-многим». На больших объёмах ещё и тормозит.
Найди и почини источник дублей.

3. Фильтры, что убивают индексы
DATE(col) = '2025-01-01' или LIKE '%abc' лишают индекс шанса работать. На тестах всё быстро, а на проде — скан миллионов строк.
Убирай функции из фильтров или храни отдельные поля для поиска.

💸 Поддержать канал
👉 Senior Data Analyst | #sql
👍5🤔1
⚠️ SQL и три ловушки, которые должен видеть Senior

Разбор трёх частых анти‑паттернов в SQL, которые встречаются даже у опытных разработчиков. Почему они опасны, как их заметить на ревью и что с ними делать.


▪️Почему важно копать глубже?

На ревью SQL‑кода легко проверить только синтаксис, названия колонок и то, что результат «похож» на ожидаемый. Но на уровне senior задачи другие:

•  Проверить бизнес‑логику — запрос должен возвращать ровно то, что задумано.
•  Обеспечить инженерное качество — избежать скрытых ошибок и деградации.
•  Гарантировать читаемость — код должны понимать и поддерживать другие.

SQL‑запросы редко живут сами по себе: они попадают в витрины, отчёты, фичи для моделей. Любой компромисс «на авось» со временем размножается и становится проблемой.


▪️Ловушка 1: LEFT JOIN, который «тихо» стал INNER

Симптом: используется LEFT JOIN, но в WHERE добавлен фильтр по колонке правой таблицы. Это меняет смысл соединения — строки без совпадений исчезают.

Опасность:
•  Тихое искажение логики: запрос, который должен возвращать всех клиентов, внезапно отбрасывает часть.
•  Проблема заметна не сразу — в отчётах «пропадают» данные.
•  Разные ожидания у участников команды.

Как обнаружить: при ревью искать конструкции LEFT JOIN + фильтр по колонкам правой таблицы в WHERE.

Что делать:
•  Переносить условие в ON, если оно относится к соединению.
•  Если соединение должно быть INNER, писать явно.
•  Для сложных фильтров предварительно отфильтровать данные правой таблицы.

▪️Ловушка 2: DISTINCT как «пластырь» на неправильный JOIN

Симптом: DISTINCT или COUNT(DISTINCT) в запросе для устранения дублей.

Опасность:
•  Скрывает причину дубликатов — чаще всего это неправильные ключи или соединение «многие‑ко‑многим».
•  DISTINCT замедляет выполнение на больших объёмах.
•  Может приводить к потере нужных данных.

Как обнаружить: задать вопрос автору: «Почему тут DISTINCT?». Проверить кардинальность соединений и условия.

Что делать:
•  Явно выбирать одну нужную строку с помощью оконных функций или подзапросов.
•  Агрегировать данные до соединения.
•  Использовать DISTINCT только там, где это действительно часть бизнес‑логики.

▪️Ловушка 3: Несаржабельные фильтры, которые убивают индексы

Симптом: в WHERE применяются функции к колонкам, используется LIKE с ведущим %, или происходит приведение типов на лету.

Опасность:
•  Индекс по колонке не используется.
•  На тестах запрос быстрый, а на бою уходит в полное сканирование.
•  Проблема проявляется при росте объёмов данных.

Как обнаружить: искать функции в фильтрах (DATE(col), LOWER(col)), проверять шаблоны поиска, смотреть план запроса.

Что делать:
•  Переписывать фильтры, чтобы индекс мог быть использован (работать с диапазонами дат, хранить предрасчитанные значения).
•  Денормализовать часто фильтруемые значения (например, выделить домен email в отдельную колонку).
•  Использовать специализированные индексы (GIN, BRIN, trigram).

▪️ Чек‑лист Senior на ревью SQL
•  LEFT JOIN + WHERE по правой таблице? → проверить логику.
•  DISTINCT / COUNT(DISTINCT)? → действительно ли нужен.
•  Кардинальность соединений ясна и контролируема.
•  Функции на колонках в WHERE? → переписать под индексы.
•  LIKE с ведущим %? → оптимизировать.
•  Индексы соответствуют условиям фильтрации.
•  План запроса не ушёл в Seq Scan без причины.

💥 Как тебе ?
🔥 — узнал(а) что-то новое
🤝 — темы хорошо знакомы

💸 Поддержать канал
👉 Senior Data Analyst | #sql
🔥9🤝1
💬 Почему сеньор не отвечает на задачу сразу?
Потому что сначала уточняет, что именно нужно.

На первый взгляд кажется, что он просто тянет время.
А на деле — экономит и своё, и твоё время.
Размытый запрос = риск запутаться в терминах, насыпать лишних данных и угробить пару часов впустую.

Обычно вопросы такие:
• Зачем нужны эти данные?
• Какие именно поля важны?
• В каком виде будет удобнее получить результат?
• Когда это критично?


2 минуты на уточнения = часы, сэкономленные на переделках.
Это не бюрократия, а страховка от бессмысленной работы.


💸 Поддержать канал
👉 Senior Data Analyst | #soft #product
🔥4🤝1
🐢 Почему сеньор не отвечает сразу: искусство уточнять задачу

Сеньор-аналитик — это не «гуру SQL, который помнит все джоины наизусть».
Это человек, который сначала задаёт вопросы, а уже потом открывает SQL.

1. Миф о «быстром ответе»
Во многих командах ценится оперативность:
— «Попросили выгрузку — сделал за 10 минут».


Но скоростьценность.

Можно потратить 10 минут на запрос, который:
никому не нужен в таком виде;
считает не те поля;
не решает исходную задачу.

В итоге — переделки, двойная работа и раздражение.
Поэтому начинаем не с кода, а с уточнений.

2. Зачем вообще уточнять
Часто заказчик описывает решение, а не проблему.

Пример:
«Скинь выгрузку по клиентам за прошлый месяц».


А на самом деле может быть, что:
нужен расчёт churn rate;
интересуют только активные клиенты;
речь про конкретный сегмент;
цель — слайд для совета директоров.

А значит фильтруем всё через призму:
Что хотим понять?
Почему нужны именно эти данные?
Как это повлияет на решение?

3. Как это выглядит на разных уровнях
Джун — берёт задачу как есть, максимум уточняет формат и дедлайн.
Мидл — спрашивает про поля, источники, фильтры; понимает ценность данных, но не всегда видит весь контекст.
Сеньор — выясняет цель, согласует метрики, проверяет, есть ли готовое решение, и предлагает самый удобный способ.

4. Мини-фреймворк SCOPE
SScope: объём, сегменты, периоды, фильтры.
CContext: какую проблему решаем и кто примет решение.
OOutput: формат — выгрузка, дашборд, автоотчёт.
PPriority: как это по срочности относительно других задач.
EExceptions: что исключаем, какие риски.

5. Кейсы
📍 Из выгрузки в дашборд
Запрос: «Скинь продажи по регионам за прошлый месяц».
После уточнений: нужен еженедельный мониторинг + доступ для 3 отделов → сделали дашборд в Tableau, экономим 15 часов в месяц.

📍 Уточнение спасло от спама мёртвым клиентам
Запрос: «Клиенты без покупок 6+ месяцев».
После уточнений: добавили фильтр “открывал рассылки за 3 месяца” → в кампанию попали только живые пользователи.

6. Когда не уточняешь
Размытые термины («активный клиент» = разные цифры у разных команд).
Неверный период (30 дней ≠ календарный месяц).
Игнор контекста (миллиард строк вместо нужной агрегации).
Срыв приоритетов (взялся за «срочную» задачу и завалил реально важную).

7. Как прокачать навык
Не бойся казаться медленным — страшнее сделать бесполезно.
Используй чек-лист вопросов.
Переформулируй задачу и жди подтверждения.
Веди базу определений метрик.

8. Пример живого диалога
— Скинь продажи по Москве за прошлый квартал.
— А для чего? Отчёт или анализ трендов?
— Для презентации руководству.
— Сравнение с прошлым кварталом или и с прошлым годом?
— И с годом тоже.
— Таблица или график?
— График.

Запрос → Excel
Результат → график с трендом и комментариями прямо в презентации.

Попробуй: на каждый новый запрос — задай хотя бы 3 уточняющих вопроса.
Посмотри, сколько переделок удастся избежать.

💥 Как тебе ?
🔥 — узнал(а) что-то новое
🤝 — темы хорошо знакомы

💸 Поддержать канал
👉 Senior Data Analyst | #soft #product
🔥14🤝1
📌 Теория: Теория вероятностей на пальцах — что должен знать каждый аналитик

Вся аналитика строится на вероятностях — даже если вы не замечаете этого.
Ниже — ключевые концепты с примерами на Python, которые пригодятся в SQL-запросах, A/B-тестах, продуктовых метриках и ML-моделях.

Краткие выводы:
P(A|B) — используется в пользовательских воронках и последовательном поведении
Байес — основа спам-фильтров, предиктивных моделей и рекомендаций
Сложение вероятностей — важно для уникальных пользователей и перекрывающихся действий
Binom/Norm/Poisson — фундамент A/B-тестов, ML и оценки редких событий

Совет
Изучайте вероятность через реальные задачи: A/B-тесты, email-рассылки, CTR, прогнозирование поведения. Тогда теория «зайдет» легко и навсегда.

Эта база позволяет перейти от описательной аналитики к вероятностной. Вернись к ней, когда будешь считать конверсии, воронки или доверительные интервалы.

💸 Поддержать канал
👉 Senior Data Analyst | #python
1🤝8🔥1
◾️ Нормализация vs Денормализация

Зачем вообще спорить про это?
Потому что в нормализации удобно жить данным, а в денормализации — людям.
Если совсем по-простому: нормализация спасает от бардака и дублей, денормализация — от длинных и медленных запросов. В нормализованном мире удобно жить данным, в денормализованном — людям. В зрелых системах нужны оба подхода — просто в разных слоях.

Нормализация
Каждая таблица про одну сущность, связи через ключи.
Целостность: «Москва» и «Moscow» не заведутся параллельно.
Обновления — в одном месте.
– Аналитика требует JOIN’ов (иногда 5–6 подряд).
👉 Лучший выбор для OLTP (CRM, биллинг, ERP).


Денормализация
Широкие таблицы: всё нужное уже под рукой.
Запросы проще и быстрее.
Отлично для BI и ML.
– Дублирование, сложнее обновлять.
👉 Оптимальна для OLAP (DWH, витрины).


В реальности не «или-или».
Архитектура обычно такая:
Staging → сырые данные,
Core → нормализованное ядро,
Marts → денормализованные витрины.


👉 Senior Data Analyst | #sql #dwh
👍5
🔹 Что такое нормализация

Нормализация — это способ организовать таблицы так, чтобы:
не дублировать одну и ту же информацию в десяти местах;
сохранять целостность (одно изменение — одно место);
• избежать аномалий при вставках/обновлениях/удалениях.
Идея простая: каждая таблица про одну сущность, связи — через ключи.

Примеры:
Пользователь и его регион лежат в разных таблицах и связываются по ключу.
Таблица заказов хранит customer_id, а не дублирует имя клиента и регион.

Когда это хорошо:
Переименовали регион — обновили одну строку в справочнике.
Нет «Москва» и «Moscow» одновременно.
Отлично работает для систем с большим количеством транзакций (CRM, ERP, биллинг).

Минусы:
Аналитика почти всегда = JOINы (иногда 5–6 подряд).
Запросы тяжелее и менее читаемы.
На больших объёмах JOINы становятся бутылочным горлышком.

Вывод: нормализация — идеальна для OLTP: важна целостность, а не скорость многотабличной аналитики.



🔹 Нормальные формы
Обычно под «нормализовали» имеют в виду до 3NF. Но давай по ступенькам:

1NF — Первая нормальная форма
Колонки атомарны: одно поле — одно значение, без списков и вложенных структур.
Строки уникальны (ключ есть).

Анти-пример: phones = '123, 456, 789'.
Правильно: выносим телефоны в отдельную таблицу user_phones.

2NF — Вторая нормальная форма
Выполнена 1NF.
Любой неключевой атрибут зависит от всего составного ключа, а не от части.

Анти-пример: таблица с ключом (student_id, course_id) и колонкой student_name. Имя зависит только от student_id → вон в students.

3NF — Третья нормальная форма
Выполнена 2NF.
Нет транзитивных зависимостей: атрибуты зависят только от ключа, а не друг от друга.

Анти-пример: employees(emp_id, dept_id, dept_name).
dept_name зависит от dept_id, а не от emp_id → отделы в отдельную таблицу.

BCNF (Boyce–Codd)
Строже 3NF: все функциональные зависимости — от суперключей.
В проде редко «доводят до идеала», но полезно понимать принцип.


Что это даёт:
1NF — атомарность, без каши в полях.
2NF — нет дублей из-за составных ключей.
3NF — модульность: меняем в одном месте.
BCNF — теория на страже порядка, на практике — точечно.


🔹 Где нормализация рулит, а где — мешает
OLTP (частые изменения, транзакции, строгая целостность) — цель номер один: качество и точность.
DWH ядро часто делают ещё более нормализованным (Data Vault), чтобы аккуратно хранить историю и связи.
BI-витринах чистая 3NF не нужна — здесь важнее удобство и скорость чтения.
👍4
🔹 Что такое денормализация

Денормализация — осознанное «расплющивание» схемы, когда мы собираем широкие таблицы с готовыми атрибутами, чтобы:
писать короткие запросы;
быстро строить графики/дашборды;
кормить ML-модели без десяти JOINов.

Примеры:
В таблице заказов уже есть имя клиента и регион (а не только customer_id).
Факт продаж содержит сразу измерения: продукт, категория, канал, дата, регион.

Плюсы:
Просто и быстро читать.
BI-инструменты «летят».
Идеально для ML-фичей: одна широкая таблица — много признаков.

Минусы:
Дублирование (Москва в миллионе строк).
Сложнее обновлять: поменялся регион → перестраиваем витрину.
Несогласованность версий, если у команд свои пайплайны.
Вывод: денормализация — выбор для OLAP: приоритет скорость чтения и удобство потребителей.


🔹 не «или-или», а «и-и»: слоистая архитектура
В реальности:
Staging (сырое): тащим из источников почти как есть. Тут возможны дубли, разные форматы — задача не потерять информацию.
Core (ядро): нормализованная модель (3NF или Data Vault) — единый словарь, «истинная версия», аккуратная историзация.
Marts (витрины): денормализованные таблицы под конкретные вопросы бизнеса (звезда, снежинка, wide-table).
Логика проста: ядро обеспечивает качество/историю, витрины — удобство/скорость.


🔹 Немного про историчность (SCD)
Когда данные меняются «понемногу и не каждый день», всплывает тема SCD.
В ядре (нормализованном) удобно хранить Type 2: отдельные записи с valid_from / valid_to. Историю поднять — не проблема.
В витрине чаще:
- либо «замораживаем» срез (snapshot) на нужную дату
- либо храним только актуальную версию.
Практический вывод: глубокая история → в нормализованное ядро; оперативная аналитика и отчёты «на сегодня» → в денормализованные витрины.

🔹 Кейсы аналитики
Кейс 1. Финансовый отчёт «как было на дату»
Финансам важно восстановить картину прошлого месяца.
Нормализация позволяет собрать справочники в состоянии на дату.
Денормализованная витрина даёт быструю выгрузку без JOINов.
Лучшее из двух миров: ядро с историей + витрина под отчёт.


Кейс 2. BI-дашборд «Продажи по регионам и категориям»
Нормализованная схема → 5 JOINов и неочевидные ошибки в фильтрах.
Денормализованная витрина → одна агрегация из «широкой» таблицы.
Для BI всегда готовим витрину, а не заставляем дашборд «склеивать» полмира.


Кейс 3. ML-признаки для модели оттока
Из ядра берём историю профиля и действий.
Во «wide»-таблице собираем признаки: сумма покупок, средний чек, частота, давность событий.
Модель учится на денормализованной таблице, но питается из нормализованной истории.


🔹 Подводные камни, о которых стоит помнить
• Несогласованные версии. Разные команды денормализуют по-своему → несколько «истин».
Решение: единый Core и централизованная сборка витрин.
• Обновления. В нормализации одно изменение = один апдейт; в денормализации иногда нужен полный пересчёт витрины.
• Производительность. JOINы на больших таблицах медленные, но и «wide» разрастаются.
Баланс зависит от задач и платформы (в облаках диски дешевле CPU — это влияет на дизайн).
• Определения метрик. «Активный клиент», «заказ», «выручка» — без чётких договорённостей цифры расползутся.
Решение: словарь метрик и контракты данных.

🔹 Архитектурные паттерны
• 3NF: чисто, предсказуемо, удобно для транзакций и истории, тяжеловато для BI.
• Data Vault: хабы-линки-сателлиты; гибкая историзация и инкрементальные загрузки; отличное ядро для DWH.
• Star Schema (звезда): факт + денормализованные измерения; любимая схема BI.
• Snowflake: «звезда», у которой часть измерений слегка нормализована — компромисс между чистотой и простотой.
• Wide Table: полностью «плоская» витрина; быстро для чтения и ML, но тяжёлая в обслуживании.

Услал читать? вот итог в одном месте
Итог в одном абзаце 👇

Нормализация делает данные надёжными и историзуемыми. Денормализация делает ответы быстрыми и удобными.
Зрелая архитектура — это staging → core → marts, где ядро отвечает за «правду», а витрины — за скорость.


💥 Как тебе ?
🔥 — узнал(а) что-то новое
🤝 — темы хорошо знакомы
🔥8👍21👌1🤝1
Библиотеки ML, которые должен знать каждый аналитик

🔹 Scikit-learn
твой первый помощник в ML. Здесь всё: от предобработки данных и обучения моделей до расчёта метрик. Подходит для MVP, A/B-тестов, скоринга, быстрых экспериментов.


🔹 Statsmodels
если важна статистическая интерпретация. Поддерживает t-тесты, ANOVA, регрессии с p-value и доверительными интервалами. Особенно полезен, когда модель нужно объяснить заказчику или прописать в отчёте.


🔹 XGBoost
лидер по точности. Работает с табличными данными, отлично справляется с задачами прогнозирования и классификации. Подходит для оценки LTV, churn, scoring-моделей. Используется в продакшн-решениях.


Вывод:
Эти 3 библиотеки закрывают 80–90% задач, с которыми сталкивается аналитик данных.

💸 Поддержать канал
👉 Senior Data Analyst | #ml #python
🔥51👍1
PySpark — это не «костыль, чтобы ноутбук не падал».
Когда данных становится слишком много, ноутбук начинает страдать.
pandas не виноват — он просто не для этого.

PySpark умеет: делить данные, крутить их в кластере и делать так, что у тебя остаётся пандасовая простота, но в масштабе.


Если ты аналитик, который хочет вырасти за пределы локальной машины и «Excel-ментальности» — PySpark открывает тебе дверь в инженерный мир, при этом не отнимая любимую гибкость Python.

🚀 Попробуй: запусти Spark локально и прогон свой pandas-пайплайн.
Увидишь, что «big data» не страшный зверь, а нормальный рабочий процесс.

💸 Поддержать канал
👉 Senior Data Analyst | #pyspark #python
👍3🔥1👏1👌1
📌 Почему аналитикам пора дружить с PySpark

Когда твои данные перестают влезать в память ноутбука, pandas превращается в чемодан без ручки.
Он хорош для прототипов и быстрых исследований, но не создан для масштаба enterprise.
Здесь на сцену выходит PySpark — не как «ещё одна библиотека», а как партнёр по данным.

▫️ PySpark = распределённое мышление
Spark — это не «ускоренный pandas».
Это система, которая делит данные на части, раскидывает их по узлам кластера и работает параллельно.
Главное отличие: Spark ленив.
Ты пишешь фильтры и группировки, а он лишь строит план (DAG).
Считается всё только тогда, когда ты попросишь результат.

Что это даёт аналитику?
обработку терабайтов без упора в память;
масштабирование от ноутбука до сотен узлов;
устойчивость к сбоям — задачи переисполняются сами;
DataFrame API, где удобно как в pandas, но возможностей — на порядок больше.

▫️Аналитика с инженерным акцентом
Представь e-commerce: заказы, логи, CRM, транзакции.
В pandas — постоянная боль. В PySpark — рабочая рутина:
читаешь данные распределённо;
приводишь к единой схеме;
считаешь метрики через оконные функции;
сохраняешь в Parquet или Delta Lake.
В итоге у тебя не скрипт «на удачу», а DAG, который можно запускать по расписанию и воспроизводить снова и снова.

▫️ Как мыслить в PySpark
Схема данных явно > чем автоинференс. Иначе арифметика может рухнуть.
Партиционирование — искусство. От него зависит скорость.
UDF — крайний случай. Встроенные функции почти всегда быстрее.
Кэшировать можно, но осторожно. Экономит время, но ест память.

▫️ Когнитивный сдвиг
Если pandas — это «данные прямо здесь и сейчас»,
то PySpark — это про описание желаемого результата.
Ты перестаёшь думать «как обработать каждую строку» и начинаешь описывать:
«Как должна измениться вся таблица».

Это требует времени на перестройку мышления, но открывает масштаб и стабильность.

▫️ PySpark в стеке
Airflow — оркестрация пайплайнов.
MLflow — хранение и воспроизводимость фичей.
Delta Lake — версияция и транзакции.
ClickHouse — real-time аналитика.
Dash/Plotly — визуализация прямо с кластера.


▫️Что получает бизнес
повторяемость без ручных выгрузок;
масштабируемость без переписывания кода;
тестируемость на сэмплах локально;
надёжность и устойчивость по умолчанию.

▫️ Подводные камни
Очень широкие таблицы (1000+ колонок).
Перекосы при join’ах (skewed data).
Эволюция схемы не всегда прозрачна.
Часовые пояса → неожиданные баги с датами.

▫️ Итог: pandas — отличное начало. Но если твои данные растут быстрее, чем память ноутбука, PySpark перестаёт быть выбором. Это необходимость.

💥 Как тебе инструмент?
🔥 — что-то новое для меня
🤝 — хорошо знаком

💸 Поддержать канал
👉 Senior Data Analyst | #pyspark #python
🔥9