Мир аналитика данных
4.58K subscribers
134 photos
3 videos
110 links
Пишу о рабочих буднях и о том как я сменила профессию.

Автор канала: @Valeria_Shuvaeva
Download Telegram
«Я в режиме реального времени поясняла структуру запросов / ответов в Postman и разбирала документацию в Swagger», — пишет аналитик, который прошел наш курс, а потом два технических собеседования в международные компании. Приятно, конечно ❤️

Если в 2025 году вы хотите:
— научиться выбирать стиль интеграции под вашу задачу;
— начать проектировать с нуля и описывать интеграции в современных стилях (API: REST, SOAP, gRPC и других, + брокеры сообщений);
— узнать как правильно собирать требования и моделировать в UML;
— подготовиться к собеседованию, решив более 100 заданий;
— запустить свой API на Python.

Значит наш курс для вас!

🚀 Начните с открытых бесплатных
уроков — переходите в бот курса и жмите «Старт»
👇
@studyit_help_bot

🚀 Скидка на курс
от канала — 1 000₽ на Stepik по промокоду ANALYST до конца апреля.
❤‍🔥4👍21🐳1
🐍 Полюбила функцию .map() — за что и почему?

Ну что, опять рабочий пример. Не сложный - все таки пятница! Недавно нужно было привести разные payment_system к человекочитаемым типам оплаты — карты РФ, карты не РФ, кредиты, оплата частями и т.д. Задача вроде простая — но очень частая: 🧹 "почистить" и структурировать данные.

💡 Решение через .map()
Выглядело это примерно так:

data = {'payment_system': ['sberbank', 'tinkoff', 'stripe', 'tinkoffcredit', 'alpha_bank_podeli'],
'amount': [1000, 2000, 1500, 3000, 2500]}
df = pd.DataFrame(data)

map_dict = {
'sberbank': 'Оплата картами РФ',
'tinkoff': 'Оплата картами РФ',
'stripe': 'Оплата картами не РФ',
'tinkoffcredit': 'Т-Банк кредит',
'alpha_bank_podeli': 'Подели (Альфа-Банк)'
}

df['payment_type'] = df['payment_system'].map(map_dict)


Я сделала категоризацию платежных систем! Круто звучит, правда? А если просто - то, применила словарь к данным в столбце. В вашем случае он заменяет названия платежных систем на их категории. Преобразование занимает одну строку — читаемо, быстро и лаконично.

🔍 Что такое .map() вообще?

.map() — метод в pandas, который применяется к Series (одному столбцу) и возвращает новую Series.
Он может принимать:

словарь — для замены значений (value: new_value) как мы и сделали

функцию — для произвольной логики

⚠️ Нюансы использования:
- Работает только с одной колонкой
- Для нескольких — нужно использовать apply().

Решение через .apply()

def get_payment_type(ps):
if ps in ['sberbank', 'tinkoff']:
return 'Оплата картами РФ'
elif ps == 'stripe':
return 'Оплата картами не РФ'
elif ps == 'tinkoffcredit':
return 'Т-Банк кредит'
elif ps == 'alpha_bank_podeli':
return 'Подели (Альфа-Банк)'
return 'Другое'

df['payment_type'] = df['payment_system'].apply(get_payment_type)

☝️Вывод:
Если нужно быстро заменить или классифицировать значения в одном столбце — .map() 🔥
Особенно удобно с категорией платежей, типов устройств, источников трафика и т.п.

Теперь это один из моих go-to инструментов 💼
Please open Telegram to view this post
VIEW IN TELEGRAM
👍29🔥9❤‍🔥54🐳1
Как не попасть в ловушку собственных выводов? 🧠

Знакомо ли вам чувство, когда кажется, что все факты подтверждают вашу гипотезу — но вдруг оказывается, что вы упустили что-то важное?

В аналитике (да и в жизни) это называется "ошибкой подтверждения" — когда мы подсознательно игнорируем данные, которые противоречат нашим убеждениям. Очень опасная штука! 🔥

Подробнее о ней писал(а) Оля в своем канале — рекомендую к прочтению.

Кстати, Оля — продуктовый аналитик с 3+ годами опыта, и у нее огромный багаж знаний о собеседованиях:
Прошла отбор в 20+ компаний (включая бигтехи)
Провела 50+ технических интервью как интервьюер
Пишет крутые разборы, например, как получить оффер после собеседования

Еще один пост, который меня впечатлил — про парадокс выбора. Это про то, почему больше возможностей — не всегда лучше. Очень близко тем, кто, как и я, долго выбирал между разными карьерными путями.

Её канал — как уютный диванчик в мире аналитики: мало шума, много смысла. Там реально есть, над чем подумать! 💡Диванные Данные 💫"
❤‍🔥8👍521
Умный LIKE: как искать по множеству URL в SQL без боли

Праздники закончились и вот уже третий день суровых будней. Давайте честно признаемся, что после стольких дней отдыха работать ну оочень лень? Я вот честно признаю - мне лениво, но приходится собирать себя по частям и делать дело, много дел, вот еще одно дело, а вот это тоже надо. То запрос на аналитику, то отчёт, то внезапные «срочно-очень-важно» Знакомо? Ну, что ж, у всех примерно такое состояние, так что ничего - выживем.

Расскажу интересный рабочий кейс — как эффективно искать записи по сотням URL в SQL. Покажу на простом примере, как избежать горы OR условий.

Допустим, у нас есть большой список URL-адресов (например, из Excel-файла), и нам нужно найти все посещения этих страниц в нашей базе данных.

Сначала создаем тестовые данные.
import pandas as pd
from pandasql import sqldf

# Мини-датасет для демонстрации
data = {
'page_url': [
'https://site.com/blog/101',
'https://site.com/blog/102',
'https://site.com/blog/103',
'https://site.com/news/101',
'https://site.com/news/102',
'https://site.com/help',
'https://site.com/blog/201',
'https://site.com/blog/202',
'https://site.com/about',
'https://site.com/contact'
],
'visitor_id': [1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010],
'visit_date': pd.date_range('2024-01-01', periods=10)
}

df_visits = pd.DataFrame(data)

Список интересующих нас блогов (как будто вы это выгрузили из excel файлика, который вам прислали коллеги, представьте что тут более 100 ссылок)
df_blogs = pd.DataFrame({
'blog_path': ['blog/101', 'blog/102', 'blog/201']
})

🌳Стандартный подход🌳
SELECT * FROM visits
WHERE page_url LIKE '%blog/101%'
OR page_url LIKE '%blog/102%'
OR page_url LIKE '%blog/201%'


🍀Автоматизированное решение 🍀

Динамически генерируем условия LIKE
conditions = " OR ".join([f"page_url LIKE '%{path}%'" for path in df_blogs['blog_path']])

query = f"""
SELECT
page_url,
visitor_id,
visit_date
FROM df_visits
WHERE {conditions}
"""
result = sqldf(query)

Если понравился способ - поставь лайк, а если вам тоже сложно работать после праздников, то добавь там еще каких-нибудь смайликов 🤪😀
Please open Telegram to view this post
VIEW IN TELEGRAM
31🔥9👏3❤‍🔥21🐳1🌚1
🔥 Ах, это чувство «я ничего не успела»

Знакомо чувство, когда вроде бы что-то делаешь, а к обеду/вечеру понимаешь, что «серьезные» задачи так и остались нетронутыми?
Вместо углубления в python — читала статьи, а то и в youtube залипала, вместо разбора сложных кейсов — читала телеграмм каналы других аналитиков , maybe даже мемчики по аналитике (ну а что, тоже развитие? 😅).

Короче, вместо жёсткого фокуса — растекалась по смежным темам, домашним делам... И вот оно — накатывает: «Я опять потратила время зря!»

Но стоп-стоп! Мы же не роботы, чтобы безостановочно генерить код и умные мысли. 🧠 Мозгу нужно «лениться», переваривать инфу, иногда просто смотреть в потолок, и даже — о ужас! — заниматься ерундой.
Это не просто норма — это необходимость!

Нельзя учиться и работать 24/7 без «пустых» промежутков — это путь к выгоранию. Даже «бесполезное» чтение иногда даёт неожиданные инсайты, да хотя бы просто отдых мозгу.
И вообще перфекционизм — главный враг прогресса. Лучше медленно, но без ненависти к себе.

Так что если вы сегодня не выжали из себя все соки и:
не стали гуру SQL
не переписали все свои запросы на оптимизированные
вообще ничего не сделали из «важного» списка

— это не провал!

Завтра будет новый день (и, возможно, опять без подвигов — и это ок 🤫)

Главное — не превращать развитие в бесконечный марафон с чувством вины!

Как вы справляетесь с мыслями что недостаточно продуктивны? 👇 Делитесь в комах — соберём коллекцию лайфхаков!
Я вот - пост написала и мне полегче стало 😂😜🤪
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2210❤‍🔥6👍43
🎁Подарим карьерные консультации от HR-эксперта!

Из разных утюгов много говорят про оптимизации и сокращения (и это факты), стагнацию зарплат и сложности в росте. Особенно в шоке те, кто давно не выходил на рынок или попал в айтишный бум и не успел застать прошлые кризисы.

Обсуждали, что сейчас происходит на рынке с Олей, у нее 9+ лет опыта в it-компаниях, ex. консультант по обучению и развитию в Райффайзенбанке, 4+ года менторит по карьере и помогает разобраться с вопросами профессиональной самореализации. Пишет про адекватную карьеру https://xn--r1a.website/olga_career

🎯 Чтобы поддержать тех, кому это сейчас нужно, мы решили подарить две консультации. Обращаться можно с любыми карьерными запросами: построить карьерный трек, написать классное резюме, подготовить самопрезентацию к интервью, выбрать новое направление для развития, поработать со страхами/ самозванцем/ выгоранием.

Что еще можно найти в канале?
✔️ Воркбук «Как найти результаты в своей работе и презентовать их», который прошел проверку выступлениями на конференциях
✔️ Икигай в карьере и жизни (узнаете, какие потребности вами движут в данный момент)
✔️ Рекомендации, как составить резюме, чтобы его захотели прочитать.

🗓 Пишите, с чем нужна помощь, в комментариях, 6 июня отпишемся, кому достанутся консультации 🙌
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤‍🔥2🔥1
📍 Я собрала для вас подборку своих постов, которые вы могли пропустить. Даже если некоторые из них вышли давно — они всё ещё огонь! Hard skills — это серьёзно, а не мемы разгонять 🤪 .

🐍 🔤🔤🔤🔤🔤🔤

- Рабочий пример отчета для отдела продаж – формирование группы клиентов по разным условиям
- Особенности pivot_table на питоне
- Примеры сводной таблица pivot_table()
- Создание диапазона дат на питоне
- Рабочий скрипт по отвалу клиентов
- Отвал клиентов с доп.условиями
- Три топ клиента за год в каждой нише
- Кумулятивная функция сumsum()
- Примеры функции transform()
- Вопросы с собеседований по Python и Pandas
- Как определить к какой стране относится номер телефона? библиотека Phonenumbers
- Скрипт по когортному анализу (часть на SQL, часть на пандасе)
- Примеры np.where()
- Регулярные выражения на Питоне. модуль re
- Как ускорить обработку 50 млн строк: переход с Python на Clickhouse. (Регулярки и оптимизация больших данных)
- Исследование среднего ценового сегмента в разрезе определенных категорий. Биннинг с помощью функции cut
- Генерация синтетических данных: разбор тестового от OZON. (Практика с NumPy и Pandas)
- Регулярки в Python: как вытащить нужные данные из текста. (Рабочий пример с re.findall)
- Группировка данных в Pandas: объединяем значения через запятую. (Полезный трюк для отчётов)
- Как правильно выбирать топ-клиентов с прерываемыми индексами? Loc и iloc
- Поиск клиентов с подпиской без перерывов с помощью shift()
- Ищу пользователей, покупающих новый тариф задолго до окончания старого
- Категоризация платежных систем с помощью map

🔤🔤🔤

- Трафик, лиды, конверсия
- SQL Between
- Вопросы с собеседований по SQL
- Тестовое с решением
- Скрипт по когортному анализу (часть на SQL, часть на пандасе)
- Примеры использования CASE
- Group by на примере из курса Карпова и на рабочем примере.
- Регулярка для Clickhouse
- Библиотека Pandasql для написания SQL кода в Jupyter Notebook
- Оконные функции в PostgreSQL: считаем рабочие часы сотрудников. Разбор LAG и FILTER
- Тестовое на SQL: отделы и зарплаты руководителей (JOIN с подзапросами и агрегация)
- Установка PostgreSQL и DBeaver: инструкция для новичков. Как работать с CSV и писать запросы локально)
- LEFT JOIN с условием в ON или WHERE: в чём разница?
- Как извлечь домены почт клиентов: хитрости SUBSTRING_INDEX
- Задача с LeetCode: находим менеджеров с 5+ подчинёнными
- Расчёт коэффициента подтверждения: разбор задачи с LeetCode
- Задача Hard на LeetCode! Department Top Three Salaries
- Задача со stratascratch про перелеты

Ну и просто лёгкое и вдохновляющее:

☹️☹️😙🤑😓😓

- Как я сменила профессию
- Какие бывают аналитики
- Мотивация
- Теория вероятности на минималках
- Как заходить в LinkedIn без VPN
- YandexGPT 2 рассказал почему стоит выбрать карьеру в аналитике данных
- Поддержка в IT: как не сдаться на пути к офферу

- Яндекс.Метрика для чайников: как анализировать трафик в Дзене
- Как войти в IT без опыта
- Прокрастинация и баланс в жизни: как не сгореть в аналитике

p.s. И не забываем про возможность выиграть консультацию, вот пост.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥358😍4
Мир аналитика данных pinned «📍 Я собрала для вас подборку своих постов, которые вы могли пропустить. Даже если некоторые из них вышли давно — они всё ещё огонь! Hard skills — это серьёзно, а не мемы разгонять 🤪 . 🐍 🔤🔤🔤🔤🔤🔤 - Рабочий пример отчета для отдела продаж – формирование…»
🐍 Pandas: Объединяем значения в группах с groupby + join

Сейчас покажу то, что стопудово вы будете часто использовать!
Когда нужно собрать в кучу разрозненные текстовые значения для каждой группы из одной колонки. Например:

☑️Собрать все платформы, на которых работал рекламный аккаунт

☑️Объединить теги товаров из одной категории

☑️Соединить комментарии пользователей

Вот 3 способа как это сделать.
Допустим, у нас есть DataFrame с рекламными расходами:
import pandas as pd
data = { 'account_id': [100, 100, 100, 200, 200, 300, 300, 300, 400, 500],
'platform': ['yandex', 'telegram', 'vk', 'yandex', 'telegram',
'vk', 'yandex', 'telegram', 'yandex', 'vk'],
'amount': [600, 300, 200, 1500, 800, 1200, 600, 400, 900, 750]
}
df = pd.DataFrame(data)


1️⃣groupby + lambda + join 💡
df_grouped = df.groupby('account_id',as_index=False)['platform'].apply(lambda x: ', '.join(x))

lambda x: ... - это анонимная функция. Можно читать как: "Для каждого x (где x — это группа платформ) выполнить join"
Не забываем именно в groupby добавлять as_index=False, а не потом .reset_index(), так как это оптимальнее. Ну и к тому же раз уж в функции groupby есть такой способ, то им надо пользоваться.


2️⃣agg() с join 🔄
df_grouped2 = df.groupby('account_id',as_index=False).agg({'platform': lambda x: ', '.join(x)})


А если обернуть x в set(x), то можно убрать дубликаты если они там есть: df.groupby('account_id',as_index=False).agg({'platform':lambda x:','.join(set(x))})

3️⃣Краткая запись ⚡️
df_grouped3 = df.groupby('account_id',as_index=False)['platform'].apply(', '.join)


Короче, это реально удобно! Вместо нескольких строк с одним account_id получаем одну строку и видим все платформы аккаунта сразу.

А какой способ используете вы? Делитесь ⬇️
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥11👍1🌚1
🔥 Аналитики vs нейросети: кто останется на плаву?
Небольшие страшилки вам тут принесла. Пугаться можно, но не сильно. А то потом на психологов тратиться еще придется.
У hh вот такая статистика по количеству вакансий на рынке труда. Почему эта метрика стремительно падает, а не ключевая, блин, ставка?

Короче, в IT количество вакансий сильно сократилось, а вот количество резюме увеличилось. Вот вам и конкуренция!
Да еще и опасение, что скоро нейросети всех заменят! Но заменят ли они нас полностью? Я считаю, что нет. Но сметут тех, кто не готов расти.

GPT сегодня (туда же deepseek и прочие)— как стажер-вундеркинд: то гениальные инсайты выдает, то несет такую дичь, что хоть стой, хоть падай. И вот тут-то пригодятся те, кто умеет его "дрессировать" — проверять, допиливать и направлять. Такие специалисты не пропадут. Остальным стоит задуматься: а что, если завтра вашу работу можно будет автоматизировать за два клика?

Рутину заберут нейросети, а работу получат только те, кто:

➡️ Глубоко разбирается в своей области (хороший жирный плюс),
➡️ Умеет думать, а не просто кликать (хотя и нейронка может думать так-то..),
➡️ Эффективно работает с ИИ и живыми людьми (огромный плюс).

📉 Почему вкатиться стало сложнее?
Раньше хватало 100 откликов на hh, чтобы получить оффер. Сейчас джуны ищут работу полгода и больше, и это если активно прокачивать соцсети и нетворкинг.

Почему так?
🔜 Компании теперь хотят мидлов или джунов с опытом (где бы им его взять, да?).
🔜Экономика тормозит — бюджеты режут.
🔜 Конкуренция выросла: вузы и курсы за компанию штампуют конкурентов.
🔜 ИИ пока не забирает вакансии, но скоро начнет. По ощущениям в ближайшую пятилетку. В магазинах уже кассиров почти нет, одни автоматы стоят.
🔜 На рынок выходит поколение мат.капитала — будет еще жестче. Те, прям со школы уже и питон и статистику изучают.

🛡 Вывод: не жди, действуй.
ИИ не остановить, но можно стать тем, кого не заменят. Учись, адаптируйся, ищи сильные стороны.
Думаете, будет еще какой-то вывод? Нет, финал открыт, как говорится.

Но есть и радостная новость - впереди 4 выходных дня и это ВАУ! 😀😀😀 Да, мы не нейронки и нам хочется отдыхать!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤‍🔥4🔥3🤬31
Можно немного личного? 🌧

Сегодня пятница, а за окном — мокро, серо и… совсем не летнее настроение. Казалось бы, мелочь: ну подумаешь, дождь! Но как же сложно иногда управлять своими эмоциями, когда реальность не совпадает с ожиданиями.

Лето мечты? Пока что «лето в режиме акварели» — размытое и невнятное. 😄 Но ведь так не только с погодой: бывает и в работе, и в отношениях, и даже в хобби. Жизнь любит сюрпризы!

Кстати, о хобби. Кто бы мог подумать, что меня затянет в аквариумистику? Но так зацепило! Рыбки стали неожиданными антистресс-терапевтами. 🐠💙

Давайте делиться настроением!
Как спасаетесь от хандры? Кидайте фото питомцев или ваших «залипательных» хобби — согреем ленту теплом!

И да, аналитика данных никуда не делась - будет настроение и появится новый разбор. А пока посмотрите на моих тернеций 😜
❤‍🔥136🔥4🤯1
📌 Разбор реальной задачи с собеседования

Недавно мне прислали одну из задач, которую дают на собеседованиях. Делитесь в комментариях, сталкивались ли с подобным - а если у вас есть другие тестовые задания (или интересные кейсы из практики), кидайте в личку! Разберём вместе. 👍

Есть таблица просмотров видео с полями:
user_id - идентификатор пользователя,
video_id - идентификатор видео,
date - дата просмотра.
1 строка - это 1 просмотр видео

Задача:
Вывести список пользователей, которые:
Смотрели видео 1 и 3,
Но не смотрели видео 2.

Создадим датафреймчик
data = {
'user_id': [1, 1, 1, 2, 2, 3, 4, 5, 5],
'video_id': [1, 2, 3, 1, 2, 4, 1, 1, 3]
}
df = pd.DataFrame(data)

Есть разные способы решения:

Способ 1: Подзапрос с исключением
query = f"""
SELECT user_id
FROM df
WHERE user_id NOT IN (SELECT user_id FROM df WHERE video_id = 2)
GROUP BY user_id
HAVING COUNT(DISTINCT video_id) = 2
result = sqldf(query)

Исключаем пользователей, которые смотрели видео 2.
Оставляем только тех, у кого ровно 2 уникальных просмотра (то есть 1 и 3). Это будет user_id=5

Способ 2: Фильтрация в HAVING
query = f"""
SELECT user_id
FROM df
GROUP BY user_id
HAVING COUNT(*) FILTER (WHERE video_id = 1) > 0
AND COUNT(*) FILTER (WHERE video_id = 3) > 0
AND COUNT(*) FILTER (WHERE video_id = 2) = 0
result = sqldf(query)

Конструкция FILTER (WHERE ...) очень удобна в задачах, где нужно проверить несколько условий одновременно. Просто шик, блеск, красота!

Способ 3 : CASE в HAVING (по сути замена Filter, в MySQL например)
query = f"""
SELECT user_id
FROM df
GROUP BY user_id
HAVING COUNT(CASE WHEN video_id = 1 THEN 1 END) > 0
AND COUNT(CASE WHEN video_id = 3 THEN 1 END) > 0
AND COUNT(CASE WHEN video_id = 2 THEN 1 END) = 0
"""
result = sqldf(query)


Какой способ лучше?
Первый — лаконичный, но это если нет других вариантов video_id.
Второй и третий — более читаемые и гибкие, особенно если нужно добавить дополнительные условия.

P.S. Если хотите добавить что-то своё или знаете альтернативные способы решения — пишите! А если у вас есть похожие задачи — присылайте, сделаем разбор. 💪🤪
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥195❤‍🔥1
📊 Задачка с собеседования: Самый дорогой товар в первой покупке
Всем привет! Сегодня разберём еще одну интересную задачку, которую часто дают на собеседованиях.

🎯 Условие задачи:
Для каждого пользователя нужно найти наименование и цену самого дорогого товара в его первой транзакции.

🔍 Исходные данные:
У нас есть:
Таблица с покупками (df_orders) - кто, когда и что покупал (user_id, transaction_datetime, item_id, order_id)
Табличка товаров (df_items) - информация о товарах и их ценах (item_id, brand, name, price)

💡 Решение с подзапросами:
select user_id,name,price
from
(
select user_id,order_id,transaction_datetime,price,name,item_id,number_bought,
row_number() OVER (partition by user_id order by price desc) as most_expensive
from(
select user_id,order_id,transaction_datetime, price,name, di.item_id,
dense_rank() OVER (PARTITION BY user_id order by transaction_datetime ) as number_bought
from df_orders do
left join df_items di on di.item_id = do.item_id
) tt
where number_bought=1
)
where most_expensive=1


🎯 Как это работает?
1️⃣ Внутренний подзапрос:

- DENSE_RANK() нумерует все покупки пользователя по времени.
- Если в одной транзакции куплено несколько товаров, у них будет одинаковый number_bought (например, все =1 для первой покупки).
dense_rank() OVER (PARTITION BY user_id order by transaction_datetime ) as number_bought


2️⃣ Средний подзапрос
- Оставляет только товары из первых покупок (WHERE number_bought = 1).
- ROW_NUMBER() сортирует эти товары по цене (дорогие — выше).
row_number() OVER (partition by user_id order by price desc) as most_expensive 


3️⃣Внешний подзапрос выбирает самый дорогой товар из первой покупки (most_expensive=1)


Альтернатива с CTE:
WITH first_purchases AS (
SELECT
user_id, price, name,
DENSE_RANK() OVER (PARTITION BY user_id ORDER BY transaction_datetime) AS number_bought
FROM df_orders
LEFT JOIN df_items USING (item_id)
),
most_expensive_items AS (
SELECT
user_id, name, price,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY price DESC) AS price_rank
FROM first_purchases
WHERE number_bought = 1
)
SELECT user_id, name, price
FROM most_expensive_items
WHERE price_rank = 1

Какой вариант вам ближе — подзапросы или CTE?

P.S. Я сейчас в отпуске 🌴☀️ и принципиально не думаю о SQL. Просто лень не только думать, но и писать. 🤪
(Но код всё равно проверила и протестила)
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍5❤‍🔥1🔥1
🔥 Вернулась из отпуска, хватит отдыхать!

Ну что, отпуск пролетел быстро, как и положено отпуску. Немного грустно...
Но зато вчера я узнала про бесплатный интенсив по А/B-тестам от ШАД! И это не реклама. Я сама записалась и уже посмотрела первую лекцию.

📌 Что крутого?
Программа – огонь: бутстрап, линеаризация, CUPED и другие важные темы.
Можно подключиться по записи (первая лекция уже есть, но всё ещё успеваешь!).
Есть ноутбуки с кодом - поковыряться, потестить циферки для практики, а это я уважаю. 💪

📅 Регистрация открыта до 25 июля. Ну грех не поделиться ХАЛЯВОЙ!

Сертификат дают только после отбора, но, честно, главное – знания, а не бумажка. 🚀
Кому совсем лень, гляньте первый ноутбук - там же красотища вообще 🎁

p.s. Если после строчки import scipy.stats у вас чешутся руки запустить симуляции — вы тот ещё симулянт! 🤪
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥133❤‍🔥1
Бигтехи vs все остальные — где лучше?

На днях в одном из блогов наткнулась на вечный спор: работать в Бигтехе или в обычной компании? Речь, конечно, не про иностранные Amazon, Apple и прочие, а именно про наш российский, родной, можно сказать, Бигтехушка. Это Яндекс, Сбер, Авито, Т-Банк, WB, OZON и прочие IT-гиганты.

Мнение, как обычно, разделились.
Одни кричат: «Работать в них “фу”. Одни овертаймы, высосут все соки!» (привет, выгорание 👋)
Другие хвалят: «Лучше места не найти! Там и ДМС, и зарплата в рынке, и вообще имя узнаваемое, а не ООО “Ромашка“ какая-то»

Выскажу свое нафиг никому не нужное мнение.
Давным давно когда я работала в финансовом отделе и делала управленческую отчетность мы задерживались в дни отчетов до часу или даже до двух часов ночи в офисе! А кто-то из коллег и еще дольше! Мы отсылали отчетность в Лондон. И потом на корпоративном такси разъезжались по домам. Компания эта называлась ГрупЭм, она входила в WPP - это британский рекламный холдинг, очень известный в рекламном мире.
И знаете что? Это не был бигтех, про неё даже не все у нас слышали, но привет, адские переработки!
Так что не угадаешь, где будет хорошо. Коллеги, правда там были замечательные! ❤️

А сколько бардака бывает в небольших компаниях наверно все знают. Минимум онбординга, максимум погружения, но зато какой профессиональный рост!

Так что вывод простой:
Работайте везде! Тащите из каждого места плюсы, а минусы вам и так завистники в панамки накидают.
Главное — не застрять там, где вас не ценят. А всё остальное — опыт. 💥
Please open Telegram to view this post
VIEW IN TELEGRAM
15👍12❤‍🔥2💯2
🔍 Регулярки на практике: ищем посты про ИИ в датасете

Сегодня покажу регулярное выражения на примере задачи: как отфильтровать датасет по ключевым словам. Такое очень часто встречается в работе.

📌 Задача
Допустим, у нас есть таблица с какими-то названиями клиентов или там, новостей, или ссылок. Нужно выбрать только те, где упоминается что-то связанное с искусственным интеллектом (или его синонимами).

🔧 Решение через регулярки

🎲 Создаём мини-датасет для примера
import pandas as pd
data = {
'title': [
'Новости про ИИ',
'Котики в тренде',
'Машинное обучение и нейросети',
'Что такое Artificial intelligence?',
'Погода на завтра'],
'domain': ['tech.ru', 'cats.com', 'ai-news.org', 'science.com', 'weather.net']
}

df = pd.DataFrame(data)


🔍 Задаём паттерн для поиска
pattern = r'\b(?:ИИ|искусственный интеллект|AI|Artificial intelligence|нейросет|машинное обучение)\b' 


🎯 Фильтруем записи, где есть совпадения в title или domain

df_final = df[
df['title'].str.contains(pattern, case=False, regex=True, na=False) |
df['domain'].str.contains(pattern, case=False, regex=True, na=False)
]


💡 Ключевые параметры:
1️⃣ pattern — что ищем (текст или регулярка).

Что внутри него: raw-строки

➡️r' ' - это raw-строки, в них экранирование не происходит. Если объяснить проще, то вот например
print(r'1\t2') Выведет: 1\t2
print('1\t2') Выведет: 1 2 (табуляция или длинный пробел)
То есть r' ' — это как видишь, так и получаешь

Границы слов (\b):
➡️ Гарантирует, что ищется целое слово, а не часть слова
➡️ Например, найдет "ИИ" в "развитие ИИ", но не найдет в каком-то слове с ошибкой типа "фииалка")

Незахватывающая группа (?:...):
➡️Группирует альтернативы, но не запоминает совпадение для последующего использования
➡️Более эффективна, чем обычная группа (...), когда не нужно извлекать совпавший текст

Альтернатива
➡️| - логический оператор "ИЛИ", разделяющий слова, которые мы ищем

2️⃣case=False — игнорировать регистр (ИИ = ии = Ии).

3️⃣regex=True (по умолчанию True) — считать паттерн регулярным выражением. Если False, ищет точное совпадение строки еще и с учетом регистра.

4️⃣na=False — пропускать NaN (возвращать False вместо ошибки).

Ну и потом фильтруем базар датафрейм df если что-то отыскалось в колонках title или domain.

🚀 Так можно анализировать какие-то большие текстовые данные, для парсинга новостей можно использовать, ну или в
фильтрации сообщений в чат-ботах.
Please open Telegram to view this post
VIEW IN TELEGRAM
12❤‍🔥4👍1
📱 Цифровая диета? Не, не пробовали.

Количество каналов в телеге растет неимоверно! Я подписана на огромное количество. Конечно почти все на «беззвучном». Рука так и тянется к телефону заглянуть к кому-нибудь почитать что-то новенькое.

🔢 Нашла статистику, что в России пользователи проводят в Telegram в среднем 39 минут в день (Mediascope, 2023).
Сейчас, в 2025, особенно в IT-сфере, цифры наверняка зашкаливают.

🌟 Хочешь отдохнуть, но мозг требует контента? Добро пожаловать в бесконечную ленту! ‼️

🔔 Поводы залипнуть в Telegram.

💼 Рабочие моменты:
🟣Грузится sql запрос - загляни в Телегу!
🟣Ждешь ответа от коллеги - перейти с его контакта на канал!
🟣Сервер лег? Пока админы поднимают - есть время на пару мемов в ТГ!
🟣На созвоне говорят не о твоей теме? Тихий скролл в Телеграм - лучший друг.

🚀 Продуктивность (или её отсутствие):
🟣 Застрял на задаче? Мозг в тупике? Переключись на ТГ - вдруг там ответ? (спойлер: нет)
🟣 Понедельник. Настроение «не хочу работать». Кого бы почитать в Телеге для вдохновения? p.s. Сегодня не понедельник, не прокатит
🟣 Сделал полезное дело? Теперь можно и залипнуть в каналы — как награда!

📱 Быт и рутина:
🟣 Едешь в метро? Рука сама тянется к Телеге! (Не на людей же смотреть?)
🟣 Завариваешь кофе? Пока кипятится - глянь что там нового в ленте!
🟣 Лежишь перед сном? Ну ладно, ещё пять минуточек скролла… Ага, как же.

А ещё этот вечный FOMO (Fear of Missing Out) - тревожное «а вдруг я пропущу что-то важное?». Листаешь ленту, а в голове:
✔️Это полезно для карьеры
✔️Тут интересный кейс
✔️А это просто забавно

Но в итоге вместо отдыха — цифровая усталость. Информации море, а толку? Ее ведь еще применить нужно, а не просто прочитать!

💬 Как у вас?
Сколько каналов реально читаете? Есть ли те, что давно в «мьюте», но жалко отписаться? Как боретесь с FOMO и инфоперегрузом? Или сдались и погрузились с головой?

Давайте обсудим — может, вместе найдём рецепт цифровой гармонии? 👇
Please open Telegram to view this post
VIEW IN TELEGRAM
👍123🔥2❤‍🔥11💯1
📊 Разбор задачи с собеседования: сравнение выручки по регионам

Ну что, так как все любят разборы задачек с собесов, то вот вам еще одна!
Нужно вывести разницу в выручке в процентах по каждому региону, сравнивая октябрь 2024 с сентябрем 2024.

📌 Структура таблиц:

region – данные о регионах и городах
- id - первичный ключ
- region_id - id региона
- region_name - название региона
- city_id - id города
- city_name - название города

payments – информация о платежах
- id - первичный ключ
- payment_id - id платежа
- dt - дата и время платежа
- amount - сумма платежа
- city_id - id города

1️⃣ Предварительный запрос. Соединяем таблицы и группируем данные.
Для начала нужно связать таблицы region и payments по полю city_id, чтобы понять, к какому региону относится каждый платёж.
Затем:
Извлекаем год и месяц из даты платежа (dt) с помощью substring(dt, 1, 7) (формат 'YYYY-MM'). Я всегда делаю это с годом на всякий случай, а то вдруг в данных разные года представлены.
Суммируем выручку (amount) по каждому региону и месяцу.
Делаем это все в CTE. По сути, просто предварительный расчет чего-либо.
🔹 CTE (Common Table Expression) — это временный результат запроса, который можно использовать в последующих частях SQL-запроса.

Вот так начинается наш CTE
with monthly_revenue as

. Теперь на основе этой таблички мы сможем делать уже основной запрос со сравнением:

2️⃣Основной запрос. Сравниваем выручку между сентябрём и октябрём
Теперь, когда у нас есть выручка по месяцам, можно рассчитать разницу в процентах между октябрём (2024-10) и сентябрём (2024-09).
Используем:
FILTER – отбирает только нужные строки для агрегации (аналог CASE WHEN).
NULLIF – защищает от деления на ноль (если в сентябре выручки не было).
Тут уже мы во FROM пишем monthly_revenue. То есть вытаскиваем из подзапроса уже данные.
query = f"""

with monthly_revenue as (
select region_id,
region_name,
substring(dt,1,7) as month, -- оставляем только год и месяц
sum(amount) as amount -- суммируем выручку
from region_df r
join payments_df p on p.city_id=r.city_id
group by 1,2,3
)

select region_id,
region_name,
((sum(amount) filter (where month='2024-10') - sum(amount) filter (where month='2024-09'))*1.0/
nullif(sum(amount) filter (where month='2024-09'), 0))*100 as rate

from monthly_revenue
group by 1,2

"""
result = sqldf(query)


💡 Итог:

Используй CTE (WITH) для сложных запросов — это как создание «временных таблиц» для удобства. А подзапросы — когда нужна быстрая вставка логики в WHERE или JOIN.
Оба подхода делают SQL мощнее, но CTE — это чище, понятнее и переиспользуемо

Кто любит CTE - ставьте 🐳, кто за подзапросы - 🦄. Ну а если и то и то любите - 🔥
Please open Telegram to view this post
VIEW IN TELEGRAM
🐳17🔥16❤‍🔥3🦄31
📊 Рабочий лайфхак: собираем данные по частям или как я победила ошибку ClickHouse с помощью chunk-загрузки

На днях пришлось доставать статистику по списку страниц из ClickHouse. Встретилась с проблемой — из-за длинного условия в WHERE по большому списку база выдавала ошибку лимита запроса.🙅

Что придумала:
🍀 Разбила список страниц на части
🍀 Для каждой части сделала отдельный запрос с OR-условиями
🍀 Всё соединила через pd.concat — получилась единая таблица

Я уже показывала как искать по множеству URL в SQL. Теперь автоматизируем и это.
У нас есть большой список URL-адресов (например, из Excel-файла), и нам нужно найти все посещения этих страниц в нашей базе данных.
Берем тестовые данные и список интересующих нас блогов (как будто вы это выгрузили из excel файлика, который вам прислали коллеги)
В этот раз возьмем для наглядности 4 url, чтобы "красиво" разбить их на две части (по два url в каждой)
blogs_df = pd.DataFrame({'blog_path': ['blog/101', 'blog/102', 'blog/201','blog/103']


И запихнем все в цирккл конечно!
chunk_size = 2
loc_list = blogs_df['blog_path'].tolist()
results = []

for i in range(0, len(loc_list), chunk_size):
chunk = loc_list[i:i + chunk_size]
print()
print('chunk - это вот что:', chunk) # посмотрим на эти части

chunk_condition = " OR ".join([f"page_url LIKE '%{path}%'" for path in chunk])

print('запихнули части в like:', chunk_condition)

query = f"""
select page_url,
visitor_id,
visit_date
FROM visits_df
where {chunk_condition}
"""
chunk_result = sqldf(query)
results.append(chunk_result)
# Объединяем результаты из всех частей
final_result = pd.concat(results, ignore_index=True)


print выведет нам при первой итерации:
chunk - это вот что: ['blog/101', 'blog/102']
запихнули части в like: page_url LIKE '%blog/101%' OR page_url LIKE '%blog/102%'

при второй итерации:
chunk - это вот что: ['blog/201', 'blog/103']
запихнули части в like: page_url LIKE '%blog/201%' OR page_url LIKE '%blog/103%'

Ну и выведет финально то, что искали. Смотрим на сгенерированного человечка, пытливо ищущего ответы (радуемся картинке - мозг отдыхает), а потом пеереводим взгляд на вывод кода справа и немного напрягаем мозг 🤪.
Please open Telegram to view this post
VIEW IN TELEGRAM
10👍3😁1🤪1🆒1