Мир аналитика данных
4.6K subscribers
139 photos
3 videos
114 links
Пишу о рабочих буднях аналитика. Тут много рабочего кода, прохождение собеседований и еще много всего полезного.
https://www.linkedin.com/in/valeriashuvaeva
Автор канала: @Valeria_Shuvaeva
Download Telegram
🎯 Вот и пролетели каникулы. Не жалею, что не сидела за компом. Мы семьей ездили на дачу, парились в баньке, жгли камин, встречались с друзьями, ездили к бабушкам, побывали на Красной площади.

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

💡 У меня появилась идея, которая поможет каждому из нас оставаться мотивированным и идти к своим целям!
Предлагаю вам простой, но эффективный инструмент — таблица для мотивации. Абсолютно бесплатно для всех.

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

😀 Как это работает? 😀

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

Когда знаешь, что за тобой наблюдают, появляется дополнительный стимул двигаться вперед. Это проверенный прием, который помогает не сойти с дистанции! 🚀

Что нужно сделать?
1️⃣ Переходите по ссылке, копируйте лист "Для копирования" и дайте ему имя - свое или любое другое, которое Вам нравится.
2️⃣ Заполняйте своими целями и курсами.
3️⃣ Начинайте действовать!

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

Не ждите идеального момента — начните сегодня! 💪 Ссылка на таблицу

Давайте делиться успехами и поддерживать друг друга! 🔥 Можно писать друг другу прям на листах. Типа "Ого, круто! Молодец!" Можно вставлять картинки и эмодзи. Короче, никак себя не ограничивать.

Напишите в комментариях, что планируете изучать или какую цель хотите достичь. 🙌

Скажу честно - после того как я это придумала, мне показалось, что возможно я зря это затеваю. Заходить, смотреть, самой отмечать свои занятия. Но это был искренний порыв помочь. Надеюсь эта инициатива реально окажется полезной!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1810👍7
Друзья, вы просто космос! Посмотрите, сколько новых задач и участников появилось в наших таблицах: тут и курсы по аналитике, и чтение книг, и даже ежедневные тренировки и йога. Кажется, мы все дружно рванули вперёд! 🚀

Кстати, для самых первых участников я уже добавила вдохновляющие картинки, а на неделе планирую порадовать такими же и тех, кто присоединился совсем недавно. 📸

Очень радует, что у многих не только “В планах” новые цели, но уже “Выполняется” сразу несколько дел: от прокачки SQL до занятий спортом. С каким кайфом я сама ставлю галочку, когда занимаюсь!

Именно так рождается настоящий драйв: каждый маленький шаг даёт огромный заряд мотивации всем остальным. Ведь когда видишь, как другие двигаются, тоже хочется включаться на полную. 🏋️‍♀️

Спасибо, что заполняете таблички и делитесь своими успехами. С таким настроем у нас точно всё получится! Продолжаем в том же духе: изучаем новое, тренируемся, растём. 💪

Тут спрашивали про лучшие курсы. Но их так много, что трудно выбрать - их действительно огромное количество. Главное начать заниматься, а где - уже не так важно. Одним курсом вы все равно не отделаетесь 😂 Знаний в нашей сфере много не бывает - постоянно нужно что-то учить и доучивать. Но, зато мозг будет прокачен. Ну и про тело не забывать тоже. А то это уже дисбаланс. А нам такое не надо. Гармония во всем! 😌 Поучился - иди и поприседай. Покодил - постой в планке, да не на графике, а на своем полу 😜

Я продолжу следить за прогрессом — и, конечно, всегда вэлкам для новых идей! 💡💡💡
📎 Табличка тут - тык
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥152
🔥 Сегодня прочитала, что Сбербанк начал масштабные сокращения в IT-подразделении Ecom.tech (это «Купер», «Мегамаркет», «Сберлогистика» и «Самокат») — некоторые команды «урежут» до 50%! 😱

Особенно грустно, что под «оптимизацию» попадают стажёры и джуны, то есть те, кто только делает первые шаги в профессии. При этом многие топ-менеджеры предпочитают сами покидать компанию, не желая увольнять подчинённых. 👥 Личный респект им!

Но что это значит для нас с вами — IT-специалистов или тех, кто только планирует стать айтишником? Рынок становится жёстче, конкуренция растёт, и учиться приходится всё активнее, ведь без постоянного развития навыков просто не удержаться на плаву. 📚💡

Чтобы быть «на гребне волны» в мире IT, не забывайте:

☝️Следим за трендами — технологии меняются быстро, и сейчас на первый план выходят etl, искусственный интеллект и машинное обучение (AI/ML).
☝️Осваивайте смежные области — DevOps, Data Science, тестирование, проектный менеджмент,кибербезопасность и информационная защита. Это расширяет кругозор и делает вас ценным специалистом. 🔧⚙️
☝️Иногда отдыхать, а то можно выгореть. Потом еще на психолога тратиться придется. 🤪
☝️Относиться ко всему проще и легче. Или в переводе "А когда было легко?"

Короче нам надо учится, учиться и еще раз учиться.
Думаете сейчас будет реклама курсов? А вот и нет. 😜
https://rb.ru/news/sber-ecom-personnel/
Please open Telegram to view this post
VIEW IN TELEGRAM
👍156😢3😁1💯1
👨‍💻Принесла вам интересную задачку: нужно выяснить, кто из клиентов продлевает тариф (подписку для приложений например) без перерывов (в нашем условном примере перерыв — это больше 30 дней между окончанием одного тарифа и началом следующего). Покажу пошагово, как это сделать с помощью shift() в pandas. Рассмотрим небольшой DataFrame для наглядности.

1️⃣ Создаём демонстрационный DataFrame 👨‍💻
import pandas as pd

data = [
# Клиент 1: у него нет перерывов (три подписки друг за другом)
{
'client_id': 1,
'start': '2023-01-01 09:15:00',
'finish': '2023-02-01 10:55:00',
'title': 'тариф1',
'amount': 1000
},
{
'client_id': 1,
'start': '2023-02-01 10:55:00',
'finish': '2023-03-01 12:30:00',
'title': 'тариф2',
'amount': 1500
},
{
'client_id': 1,
'start': '2023-03-01 12:30:00',
'finish': '2023-04-01 09:00:00',
'title': 'тариф3',
'amount': 2000
},

# Клиент 2: между вторым и третьим тарифом появляется перерыв больше 30 дней
{
'client_id': 2,
'start': '2023-01-07 11:00:00',
'finish': '2023-02-07 10:45:00',
'title': 'тариф1',
'amount': 1200
},
{
'client_id': 2,
'start': '2023-02-07 10:45:00',
'finish': '2023-03-07 11:15:00',
'title': 'тариф2',
'amount': 1400
},
{
'client_id': 2,
'start': '2023-04-15 09:20:00',
'finish': '2023-05-15 10:00:00',
'title': 'тариф3',
'amount': 2100
},

# Клиент 3: тоже без перерывов (три тарифа подряд)
{
'client_id': 3,
'start': '2023-01-12 08:50:00',
'finish': '2023-02-12 10:05:00',
'title': 'тариф1',
'amount': 1000
},
{
'client_id': 3,
'start': '2023-02-12 10:05:00',
'finish': '2023-03-12 09:55:00',
'title': 'тариф2',
'amount': 1200
},
{
'client_id': 3,
'start': '2023-03-12 09:55:00',
'finish': '2023-04-12 10:10:00',
'title': 'тариф3',
'amount': 1400
},
]

df = pd.DataFrame(data)
df['start'] = pd.to_datetime(df['start'])
df['finish'] = pd.to_datetime(df['finish'])


2️⃣Ищем дату окончания предыдущего тарифа 🧑‍💻
Сгруппируем по client_id и применим shift(1), чтобы «сдвинуть» finish на одну позицию вниз:

df['prev_finish'] = df.groupby('client_id')['finish'].shift(1)

Теперь в каждой строке появляется столбец prev_finish — конец предыдущего тарифа этого же клиента (или NaN, если предыдущей записи нет).

3️⃣Считаем «gap» в днях 👨‍💻
df['gap'] = (df['start'] - df['prev_finish']).dt.days

В gap получаем, сколько дней прошло между началом текущего тарифа и концом предыдущего.

Если gap > 30, считаем это перерывом и помечаем такой случай в поле check:
df.loc[df['gap'] > 30, 'check'] = 1

4️⃣Ищем тех, кто никогда не уходил в перерыв
1.Собираем «провинившихся» клиентов (у кого есть перерывы):
accounts_with_gap = tuple(set(df.loc[df['check'] == 1, 'client_id']))

2. Фильтруем все строки, в которых check не равен 1, — то есть записи без перерыва. Здесь мы берём только те покупки (строки), где не обнаружено gap > 30, то есть не поставлен check = 1.
df_winner = df[df['check'] != 1]

3.Исключаем из этого списка клиентов, попавших в accounts_with_gap:
df_winner_only = df_winner[~df_winner['client_id'].isin(accounts_with_gap)]

Теперь в df_winner_only останутся исключительно «идеальные» клиенты, у которых не было ни одного перерыва (в нашем примере это клиенты №1 и №3).

5️⃣Готово!
Таким образом, мы выявили, что:
У клиента 2 есть перерыв между тарифом №2 и тарифом №3 (пропуск более 30 дней).
Клиенты 1 и 3 идут без разрыва.
👆 Вот такой простой и мощный приём с shift() если нет оконок в sql часто выручает, когда нужно сравнивать строки внутри «своей» группы. Надеюсь, было полезно!
Please open Telegram to view this post
VIEW IN TELEGRAM
20👍17❤‍🔥7
👍 Задачка с LeetCode. Найти имя менеджера, у которого 5 или больше подчиненных.
Все знают, что решать задачи на LeetCode полезно как для прокачки мозга, так и для подготовки к собеседованиям. Но времени на это хватает не всегда, а вот разобраться, что там вообще решается, хочется. Поэтому я решила делиться с вами готовыми решениями! Сегодня у нас задача уровня Medium — разберем вместе (вот она).

Чтобы можно было потестить решение, напишу его с помощью библиотеки pandasql в Jupyter Notebook. Библиотека позволяет выполнять SQL-запросы прямо в Юпитере, а вместо базы можно просто создавать DataFrame.

Итак, в этом задании требуется написать SQL-запрос, чтобы найти всех менеджеров, у которых как минимум 5 прямых подчиненных.
Таблица Employee:
id : первичный ключ (уникальный идентификатор сотрудника).
name : имя сотрудника.
department
: департамент сотрудника.
managerId : id менеджера этого сотрудника.


Если managerId равен NULL, значит у сотрудника нет менеджера, то есть он и есть шеф.
Никакой сотрудник не будет являться своим собственным менеджером.

Мы видим, что у менеджера с id = 101 (John) есть 5 подчиненных: Dan, James, Amy, Anne и Ron.
Его (John) нам и нужно получить в ответе.

1️⃣Создаем данные для дальнейшего тестирования кода. В data записаны сотрудники, их id, департамент и id их менеджеров. Преобразуем это в DataFrame.
import pandas as pd
from pandasql import sqldf

data = {
"id": [101, 102, 103, 104, 105, 106],
"name": ["John", "Dan", "James", "Amy", "Anne", "Ron"],
"department": ["A", "A", "A", "A", "A", "B"],
"managerId": [None, 101, 101, 101, 101, 101]
}
employee = pd.DataFrame(data)

2️⃣SQL-решение:

🔹Вложенный SQL-запрос:
- Сначала группируем сотрудников по managerId, чтобы можно было посчитать их кол-во.
- Оставляем только тех менеджеров, у которых 5 или больше подчиненных.

🔹Внешний запрос:
- Находим имена этих менеджеров по их id.

3️⃣Получаем имя менеджера, у которого 5 или больше подчиненных.
query = """
SELECT name
FROM employee
WHERE id in (
SELECT managerId
FROM employee
GROUP BY managerId
HAVING COUNT(*) >= 5
)
"""
sqldf(query)


Это задание помогает разобраться, как использовать группировку (GROUP BY) и фильтрацию с HAVING. Эти навыки часто нужны в реальной работе.

Если вам такой разбор понравился, накидайте реакции! Буду разбирать задачки с LeetCode дальше. 🚀
Please open Telegram to view this post
VIEW IN TELEGRAM
40🔥10🐳63👍3
👍 Задачка с LeetCode. Расчет коэффициента подтверждения

🔍 Пришло время для следующей задачки с LeetCode.

У нас есть две таблицы:
Signups — информация о регистрации пользователей:
- user_id — уникальный идентификатор пользователя.
- time_stamp — время регистрации.

и Confirmations — информация о подтверждении действий пользователей:
- user_id — идентификатор пользователя.
- time_stamp — время подтверждения.
- action — результат действия (confirmed или timeout).

🌟Нужно: Посчитать коэффициент подтверждения для каждого пользователя — это доля успешных подтверждений (confirmed) от общего числа запросов. Если у пользователя не было запросов, коэффициент равен 0. Результат округляем до двух знаков после запятой.

Задачка уровня Middle. Вроде не сложная, но самое смешное, что я больше намучалась с округлением ROUND. В Юпитере же мы используем pandasql, а тут на сайте нужно Postgresql. Но обо всем поподробнее.

Сначала создадим тестовые данные:
import pandas as pd

signups_data = {
'user_id': [3, 7, 2, 6],
'time_stamp': [
'2020-03-21 10:16:13',
'2020-01-04 13:57:59',
'2020-07-29 23:09:44',
'2020-12-09 10:39:37'
]
}
signups = pd.DataFrame(signups_data)

confirmations_data = {
'user_id': [3, 3, 7, 7, 7, 2, 2],
'time_stamp': [
'2021-01-06 03:30:46',
'2021-07-14 14:00:00',
'2021-06-12 11:57:29',
'2021-06-13 12:58:28',
'2021-06-14 13:59:27',
'2021-01-22 00:00:00',
'2021-02-28 23:59:59'
],
'action': [
'timeout',
'timeout',
'confirmed',
'confirmed',
'confirmed',
'confirmed',
'timeout'
]
}
confirmations = pd.DataFrame(confirmations_data)

#Финальный запрос для LeetCode выглядит так:
SELECT
tt.user_id,
ROUND(count_confirmed::NUMERIC / count_all, 2) AS confirmation_rate
FROM (
SELECT
sd.user_id,
COUNT(*) FILTER (WHERE action = 'confirmed') AS count_confirmed,
COUNT(*) AS count_all
FROM signups sd
LEFT JOIN confirmations cd
ON cd.user_id = sd.user_id
GROUP BY 1
) tt;

А вот в Юпитере вместо ROUND(count_confirmed::NUMERIC / count_all, 2) AS confirmation_rate нужно сделать по другому: round(cast(count_confirmed AS FLOAT)/count_all,2) AS confirmation_rate.

Объяснение скрипта
1️⃣. Вложенный запрос:
Считаем общее количество запросов (count_all) и подтвержденных действий (count_confirmed) для каждого пользователя.
Применяем FILTER для выделения только действий confirmed. Можно было и простым where обойтись, но это скучнее, вот и повыпендриваться захотелось. 🤪

2️⃣ Основной запрос:
Делим count_confirmed на count_all для каждого пользователя.
Используем многострадальный ROUND для округления результата до двух знаков после запятой. В случае юпитера через cast для приведения count_confirmed к типу FLOAT перед делением. В случае Leetcode - к типу FLOAT приводим через ::NUMERIC
Теперь деление будет выполняться в дробных числах, а не в целых.

А еще отвлекающий маневр - колонка time_stamp в таблице Signups. Она тут не нужна, но зачем-то есть. Не люблю лишние данные в задачках 😜

Итог
Этот запрос поможет отработать ключевые SQL-концепции, такие как FILTER, LEFT JOIN и группировка, а также построить наглядный расчет метрик.

Попробуйте сами — это отличная практика!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤‍🔥3🔥3
Ребята, привет! 👋

Наверняка многие из вас знают Пашу Бухтика и его канал No Data No Growth. Уже 10 марта у него стартует курс по A/B-тестированию!
📢 Вот его пост с подробностями: https://t.iss.one/nodatanogrowth/730

🎁 Для вас есть 5% скидка – просто скажите, что вы «от Валерии / мира аналитики данных».
Это не реклама (она будет позже 😜), просто я сама иду на курс и зову вас с собой! 🚀
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤‍🔥2🤣21
🏆 Кто будет первым в рейтинге?🏆
Я немного запустила нашу табличку мотивации… В том смысле, что сама исправно ставлю свои галочки ✔️, но вот новых мотивационных картинок уже больше недели никому не раздавала. И тут мне написали об этом – с сожалением!

И знаете, это меня замотивировало 🤪!

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

📌 СЧЁТЕСЛИ(ДВССЫЛ("'" & A5 & "'!AY:BE"); "
✔️")

🍀 Как это работает?
🔹A5 — ячейка с названием личного листа.

🔹ДВССЫЛ("'" & A3 & "'!A:ZZ") — подставляет название листа и диапазон всех колонок A:ZZ. INDIRECT (в английской версии)

🔹СЧЁТЕСЛИ(..., "✔️") — подсчитывает количество галочек по всему листу!

💡 А я, кстати, даже не знала, что можно считать не только цифры, но и эмодзи!

А теперь к самому важному — кто молодцы? 💪
🔥 Кирилл Н, Ира idhril, Валерия Б, Владимир, Лера (не я, другая!) — вы большие умницы! Вы запланировали, чему хотите научиться, и уверенно идёте к своей цели.

❗️ Мотивация — это не про «пересилить себя». Не нужно делать через силу. Главное — желание, а поддержка и вдохновение от других сделают своё дело. В этом и есть уникальность проекта.

Открыта ко всем предложениям по улучшению. Вот думаю, может медальки отрисовать красивые и в конце недели раздавать первые места? Как Вам идея?

P.S. Если вдруг пропустили, о чем вообще речь, вот тут и тут про наши мотивационные таблички. Заглядывайте — возможно, это как раз то, чего вам не хватало для продуктивности! 😉
Please open Telegram to view this post
VIEW IN TELEGRAM
8❤‍🔥3
👍 Решила задачку уровня Hard на LeetCode! Department Top Three Salaries

Полистала я список задач из блока SQL 50 на LeetCode и наткнулась на одну единственную задачку уровня hard. Решила проверить свои силы и решить ее. Задача относится к уровню Hard. Давайте разберем, что нужно было сделать и как я с этим справилась. 💼💡

📝 Условие задачи:
У нас есть две таблицы:

1️⃣Employee с колонками: id, name, salary, departmentId.

2️⃣Department с колонками: id, name.

Задача: найти сотрудников, которые входят в топ-3 по зарплате в каждом департаменте. При этом нужно учитывать только уникальные зарплаты. То есть, если несколько сотрудников имеют одинаковую зарплату, они занимают одно и то же место в рейтинге.

Для решения задачи я использовала SQL с функцией DENSE_RANK(), которая позволяет ранжировать сотрудников по зарплате внутри каждого департамента. Решала тестировала в юпитере. Вот как это выглядит:

import pandas as pd
from pandasql import sqldf
employee_data = {
'id': [1, 2, 3, 4, 5, 6, 7],
'name': ['Joe', 'Henry', 'Sam', 'Max', 'Janet', 'Randy', 'Will'],
'salary': [85000, 80000, 60000, 90000, 69000, 85000, 70000],
'departmentId': [1, 2, 2, 1, 1, 1, 1]
}

Employee = pd.DataFrame(employee_data)

department_data = {
'id': [1, 2],
'name': ['IT', 'Sales']
}

Department = pd.DataFrame(department_data)

Я покрутила данные и так и так и поняла, что мне проще сделать с оконкой такое задание. Можно и подзапросом конечно решить, но на мой взгляд оконка тут просто идеально подходит.
query = """
select Department,Employee,Salary
from
(SELECT d.name as Department,
e.name as Employee,
salary as Salary,
dense_rank() OVER (PARTITION BY d.name order by salary desc) as rank
FROM Employee AS e
LEFT JOIN Department d on d.id=e.departmentId
order by d.id, salary desc
)
where rank <=3
"""
sqldf(query)


💡DENSE_RANK() позволяет ранжировать сотрудников по зарплате, при этом сотрудники с одинаковой зарплатой получают одинаковый ранг.

💡PARTITION BY d.name группирует данные по департаментам.

💡ORDER BY salary DESC сортирует зарплаты по убыванию.

В итоге мы выбираем только те строки, где ранг меньше или равен 3.

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

P.S. Кстати за прошлую неделю я выдала медали в нашем рейтинге. 🥇🥈🥉Заглядывайте и присоединяйтесь!
Please open Telegram to view this post
VIEW IN TELEGRAM
17👍14❤‍🔥4
Подъехало исследование по 2024! Смотрим, изучаем, анализируем. 📈📊
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥 Исследование рынка аналитиков 2024: полные результаты

Мы опросили 1293 аналитиков 6-ти специализаций и готовы рассказать вам:

Какие задачи решают аналитики

Что с релокацией у аналитиков

Сколько зарабатывают аналитики

ТОП и анти-ТОП компаний для аналитиков

Что ценят в аналитической культуре

За какими экспертами следят аналитики

Будем рады, если вы поделитесь результатами исследования с коллегами, знакомыми, друзьями аналитиками и всеми, кому может быть интересно 🫶

👉 Смотреть полные результаты

Все, кто принял участие в нашем исследовании и оставлял почту, проверьте её! От нас должно прийти письмо с приглашением на закрытый стрим для респондентов 🙏

💙 Команда NEWHR анализирует IT-рынок в России и других странах. Мы делаем публичные и заказные исследования для компаний (смотреть примеры). Будем рады сделать исследование вместе с вами.

📨 Пишите на почту [email protected]
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥951
Подписчик прислал мне интересную задачку с stratascratch.com, и я не могла устоять, чтобы не решить её.
Нужно найти самый дешёвый путь между городами, учитывая варианты с пересадками (до двух).

📌 Дано:
Есть таблица da_flights, в которой:
✈️ origin – пункт отправления
✈️ destination – пункт назначения
✈️ cost – стоимость перелёта

Чтобы найти маршруты с пересадками, нам нужно соединить таблицу саму с собой (self-join).

🛠 Решение

1️⃣ Прямые рейсы (без пересадок) — просто берём origin, destination, cost.

2️⃣Рейсы с одной пересадкой — соединяем таблицу саму с собой (JOIN), где f1.destination = f2.origin. Это значит, что первый рейс прилетает в город, из которого отправляется второй.

3️⃣ Рейсы с двумя пересадками — соединяем таблицу трижды (JOIN), добавляя ещё один уровень соединения (f2.destination = f3.origin).

4️⃣Объединение всех маршрутов:
Используем UNION для объединения всех трех типов маршрутов (прямые, с одной и двумя пересадками).

5️⃣Группируем GROUP BY origin, destination и выбираем минимальную цену MIN(total_cost). Жаль нельзя по таким ценам реально на морюшко улететь 🌊🌊🌊

6️⃣Сортируем результат по городу отправления и городу назначения.

Создадим табличку с данными:
import pandas as pd 
from pandasql import sqldf

data = {
'id': [1, 2, 3, 4, 5, 6],
'origin': ['SFO', 'SFO', 'SFO', 'DFW', 'DFW', 'JFK'],
'destination': ['JFK', 'DFW', 'MCO', 'MCO', 'JFK', 'LHR'],
'cost': [500, 200, 400, 100, 200, 1000]
}

da_flights = pd.DataFrame(data)

Ну и сам основной запрос:
query = """
SELECT
origin,
destination,
MIN(total_cost) AS min_price
FROM (
-- Прямые рейсы
SELECT origin, destination, cost AS total_cost
FROM da_flights
UNION
-- Рейсы с одной пересадкой
SELECT f1.origin, f2.destination, f1.cost + f2.cost AS total_cost
FROM da_flights f1
JOIN da_flights f2 ON f1.destination = f2.origin
UNION
-- Рейсы с двумя пересадками
SELECT f1.origin, f3.destination, f1.cost + f2.cost + f3.cost AS total_cost
FROM da_flights f1
JOIN da_flights f2 ON f1.destination = f2.origin
JOIN da_flights f3 ON f2.destination = f3.origin
) AS all_flights
GROUP BY origin, destination
ORDER BY origin, destination
"""

result = sqldf(query)
print(result)


Большое решение, но если по частям разобрать, то разобраться проще. Для этого вот вам ноутбук с этим скриптом. экспериментируйте!
Ну и всем отдыха на море в этом году! 🏖🏖🐠🌊
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥163❤‍🔥3👌1
🎈 Два года, 4000 человек и неожиданный результат

Друзья, нас уже больше 4000! 🎊 И для меня это просто невероятно!

Этот канал живёт без контент-плана — я пишу что хочу и когда хочу. ✏️ Это моё хобби, которое за два с лишним года превратилось в приятный источник дополнительного дохода. 💫 Когда я создавала канал чуть больше двух лет назад, даже не думала, что ко мне будут приходить рекламодатели. 🤯 Некоторых я отсеиваю, проверенных рекламирую, а кого-то — вообще бесплатно.

Помните, я писала модуль курса аналитики для SkillFactory? 📚 Меня пригласили туда благодаря этому каналу. Сейчас многие говорят про личный бренд, про то, что чем активнее ты в инфополе, тем больше возможностей к тебе приходит. И это правда!

Но ведь всё началось с простого желания выразиться. ✍️ Хотелось рассказать свои мысли, показать, что я умею, поделиться тем, как я к этому пришла. Я люблю цифры, но люблю и слово — ведь именно слово способно вдохновить… или, наоборот, сломать и обрубить крылья.🦋

И вообще спасибо, что вы здесь. 😊 За то, что читаете, комментируете, делитесь мыслями.❤️

Часто спрашивают: «Стоит ли заводить свой канал, если я ничего особенного не знаю и не умею?»
Отвечаю: ДА, стоит! 💚 Определённо стоит!

Ведь каналы ценны не только скриптами и лайфхаками. Они отражают вашу уникальность, ваш путь, который может вдохновить других. Не боги горшки обжигают! 😉 Все мы неидеальны, все сомневаемся, все волнуемся перед сложными задачами… Но мы продолжаем, потому что нам нравится то, что мы делаем. 💖

🚀 Так что, если у вас есть желание выразиться - дерзайте! Ваш уникальный голос может стать источником вдохновения для многих. 🌟
📡 А если у вас уже есть канал, пусть даже маленький – кидайте его в комментарии! Давайте поддерживать друг друга! 🌍🤗
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2420👏7❤‍🔥5🖕1
📚 Бесплатное приложение для любителей книг!

Ребята из Whattoread – друзья моих друзей, и я с радостью рассказываю о их проекте. Они создали классное книжное приложение, которое помогает найти именно вашу книгу – не просто популярную, а ту, которая действительно вам понравится, ориентируясь на ваш вкус.

🔥 Скачать на Android

От команды:
"Мы верим, что хорошая книга должна увлекать с первых страниц. Поэтому сделали систему, которая подбирает книги именно под вас. Будем рады вам и вашим отзывам!"

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

🧐 А еще они написали классную статью на Хабр:

📌 "Где взять опыт в ИТ?" О том, как создать свой первый проект, с какими трудностями сталкиваются новички и что из этого выходит. Полезно и вдохновляюще!

Короче, рекомендую! 💡📖

P.S. А завтра разберем интересную рабочую задачу. Сегодня — читаем, завтра — кодим. Идеальный ведь баланс? 🤓🚀
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥8👍4
📊 Как найти пользователей, покупающих новый тариф задолго до окончания старого?
Сегодня я хочу поделиться интересной задачей, с которой столкнулась в работе.
Нужно было найти пользователей, которые купили новый тариф до того, как закончился их текущий. Вот такое вот бывает, ага.
Давайте разберем, как это можно сделать с помощью Python и библиотеки Pandas. 🐼

1️⃣ Создание тестового DataFrame с данными о пользователях, их тарифах, датах заказа и окончания тарифов. 📝
import pandas as pd
data = {
'user_id': [1, 1, 2, 2, 3, 3],
'title': ['Тариф A', 'Тариф B', 'Тариф A', 'Тариф A', 'Тариф C', 'Тариф C'],
'дата заказа': pd.to_datetime(['2024-03-01', '2024-03-20', '2024-03-05', '2024-03-25', '2024-03-10', '2024-03-15']),
'finish_at': pd.to_datetime(['2024-04-01', '2024-05-01', '2024-04-02', '2024-04-30', '2024-04-10', '2024-05-10'])
}
df = pd.DataFrame(data)

2️⃣Сортировка данных: Сортируем по пользователю и дате заказа
df = df.sort_values(by=['user_id', 'дата заказа'])


3️⃣Использование функции shift:
Для каждого пользователя находим дату следующей покупки с помощью функции shift. Это позволяет нам сравнить дату окончания текущего тарифа с датой следующей покупки.
df['next_created_at'] = df.groupby('user_id')['дата заказа'].shift(-1)


4️⃣Вычисляем разницу в днях между окончанием текущего тарифа и следующей покупкой.
df['time_difference'] = (df['finish_at'] - df['next_created_at']).dt.days


5️⃣Проверка на изменение тарифа: Проверяем, что новый тариф отличается от старого. Для этого с помощью shift проставляем следующий тариф напротив текущего
df = df.copy()
df['next_title'] = df.groupby('user_id')['title'].shift(-1)


6️⃣Оставляем только тех пользователей, которые купили новый тариф задолго до окончания текущего (например, за 7 дней до окончания).
df_filtered = df[(df['time_difference'] > 7)] 

df_filtered = df_filtered[df_filtered['title'] != df_filtered['next_title']]


Вот мы и нашли одного пользователя user_id=1, который меняет тариф c Тарифа А на Тариф B, не дожидаясь окончания первого.

Такой анализ можно применять для таргетированной рекламы, персонализированных предложений, ну и далее по списку..
Кто уже использовал shift() — жмем 🤝, кто взял на заметку — ✍️.
Please open Telegram to view this post
VIEW IN TELEGRAM
17🤝9❤‍🔥4👍1😴1
🔥 Тестовая задача по SQL! 🔥

На собеседованиях встречаются задачки, где нужно ранжировать данные, но без оконок RANK() и DENSE_RANK(). Как такое решать? Давайте разберём её шаг за шагом!

🏆 Задача:
Есть таблица с именами и баллами. Нужно проставить ранги участников в порядке убывания баллов без использования оконных функций.

import pandas as pd
import sqlite3
from pandasql import sqldf

# Данные для таблицы
data1 = {
'name': ['Владимир', 'Иван', 'Кирилл', 'Марк', 'Алексей', 'Максим'],
'score': [20, 16, 4, 7, 11, 18]
}
df = pd.DataFrame(data1)

query1 = """
SELECT
t1.name,
t1.score,
COUNT(t2.score) + 1 AS rank -- +1 потому что считаем количество строк с большим баллом
FROM df t1
LEFT JOIN df t2 ON t1.score < t2.score -- соединяем таблицы, чтобы сравнить баллы
GROUP BY t1.name -- группируем по имени
ORDER BY t1.score DESC; -- сортируем по убыванию баллов
"""

result = sqldf(query1)


Как это работает?
1️⃣ Соединяем таблицу (LEFT JOIN) саму с собой, чтобы сравнить баллы. Сравниваем каждую строку с другими, чтобы найти, у скольких участников балл выше.

2️⃣ Группировка (GROUP BY) – для каждого имени считаем, сколько раз его балл меньше других.

3️⃣ Ранжирование (COUNT + 1) – Чтобы не с нуля ранг был. Например если у участника балл меньше, чем у 2 других, его ранг будет 3 (т.к. он третий). Вот и готов порядок мест!

Полезная и прикольная задачка. Тут и условие ON t1.score < t2.score помогает лучше понять как соединяются таблицы.
Умение решать такое "вручную" ценится.

🎯Попробуйте сами! Меняйте данные, добавляйте условия – это отличный способ закрепить знания.
9👍8❤‍🔥4👏4
🔥 Выгорание в моде?
Вижу, как многие жалуются на выгорание. Особенно молодые. Те, кто уже стал лидом или начальником какого-то направления. И у меня каждый раз один и тот же вопрос: а о чём вы думали раньше?

Быть руководителем — это не «теперь у меня зарплата пятьсот и свой проект». Это — постоянная тревожность, дедлайны в голове даже по выходным, ответственность за людей, стресс, от которого не отключиться. Чем выше залез — тем сильнее бьют. Ну правда.

Куда вы так спешите? В 25 — уже «бАльшой начальник», а в 30 — выгоревший, с пустыми глазами и отсутствием желания вообще что-то делать. Деньги? Да, хочется. Но их хочется всегда! Только лучше прийти к ним с опытом, крепкой психикой и осознанностью, чем на износе, полуживым и без удовольствия от жизни.

Амбиции — это хорошо, но если слишком тяжело выносить работу, могут и вынести вперёд ногами. А оно нам надо?

Быстрые взлёты только выглядят красиво. И психологам, кстати, выгодно — поток клиентов стабильный.

Отдыхайте, не геройствуйте — выходные уже на подходе! 🆒🆒🆒
Please open Telegram to view this post
VIEW IN TELEGRAM
👍30❤‍🔥96💯5
🎓 Продвинутая аналитика Яндекс.Метрики для маркетологов — теперь бесплатно на Stepik!

Ровно год назад я вынашивала идею: а можно ли поиграться с Яндекс.Метрикой, не создавая полноценный сайт? 📊
Ответ нашёлся — можно! Я прикрутила счётчик к каналу на Дзене и начала изучать поведение пользователей прямо оттуда: сколько людей пришли, что читали, какие статьи заходят лучше всего.

➡️Об этом я подробно писала в посте:

А теперь хочу поделиться крутым бесплатным курсом, который отлично дополнит этот опыт.

👨‍🏫 Друг моего друга запустил курс на Stepik: "SQL для маркетинга. Продвинутая аналитика данных Яндекс.Метрики".
Да, бесплатно, да, полезно, да, от души — таких инициатив всегда хочется поддержать ❤️

Если вы работаете с метрикой, хотите прокачать SQL именно под задачи анализа трафика, понимать поведение пользователей и строить крутые отчёты — загляните. Уверена, вам понравится!

📌 Учим тут https://stepik.org/course/192052
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥28🔥186🥰3👍1
Удалёнка — кайф или кому как? 🧳🏡

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

Когда-то мне искренне нравился офис: обеды в кафешках с коллегами 🍝, кофе-брейки ☕️, живые разговоры, лица в метро, смена обстановки, движ — всё это давало ощущение движения, жизни, причастности.

Но как только появилась возможность быть ближе к детям — забирать их из школы 🏫, готовить дома 🍳, водить на кружки 🎨 — я даже не сомневалась. Удалёнка — это просто спасение для родителей. Реально шик, топ, красота!

Иногда скучаю по «поболтать с коллегами в кафешке». Но сейчас это как бизнес-класс — красиво, но мимо.

Удалёнка — не универсальный кайф, но для меня в этом этапе жизни — это то, что нужно.

💬 Кто-то обожает полный ремоут. Кто-то прётся от офисной движухи.

А вы как работаете? Какой ритм вам комфортен? А может у вас гибрид?
11🔥6
«Я в режиме реального времени поясняла структуру запросов / ответов в Postman и разбирала документацию в Swagger», — пишет аналитик, который прошел наш курс, а потом два технических собеседования в международные компании. Приятно, конечно ❤️

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

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

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

🚀 Скидка на курс
от канала — 1 000₽ на Stepik по промокоду ANALYST до конца апреля.
❤‍🔥4👍21🐳1