TGViewer
Channel Public Channel
Мир аналитика данных

Мир аналитика данных

@analysts_world

Пишу о рабочих буднях аналитика. Тут много рабочего кода, прохождение собеседований и еще много всего полезного.
https://www.linkedin.com/in/valeriashuvaeva
Автор канала: @Valeria_Shuvaeva
Subscribers
4.56K
Photos
143
Videos
3
Links
114

Showing posts older than #237 · Back to latest

Older Posts 20 shown
Post #235 2.46K
🔥 Выгорание в моде?
Вижу, как многие жалуются на выгорание. Особенно молодые. Те, кто уже стал лидом или начальником какого-то направления. И у меня каждый раз один и тот же вопрос: а о чём вы думали раньше?

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

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

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

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

Отдыхайте, не геройствуйте — выходные уже на подходе! 🆒🆒🆒
  • 👍 30
  • ❤‍🔥 9
  • ❤ 6
  • 💯 5
Post #233 2.79K
🔥 Тестовая задача по 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
Post #231 2.34K
📊 Как найти пользователей, покупающих новый тариф задолго до окончания старого?
Сегодня я хочу поделиться интересной задачей, с которой столкнулась в работе.
Нужно было найти пользователей, которые купили новый тариф до того, как закончился их текущий. Вот такое вот бывает, ага.
Давайте разберем, как это можно сделать с помощью 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() — жмем 🤝, кто взял на заметку — ✍️.
  • ✍ 17
  • 🤝 9
  • ❤‍🔥 4
  • 👍 1
  • 😴 1
Post #230 2.05K
📚 Бесплатное приложение для любителей книг!

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

🔥 Скачать на Android

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

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

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

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

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

P.S. А завтра разберем интересную рабочую задачу. Сегодня — читаем, завтра — кодим. Идеальный ведь баланс? 🤓🚀
Google Play What to read? - Apps on Google Play The books recommendation system
  • ❤‍🔥 8
  • 👍 4
Post #228 2.71K
🎈 Два года, 4000 человек и неожиданный результат

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

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

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

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

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

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

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

🚀 Так что, если у вас есть желание выразиться - дерзайте! Ваш уникальный голос может стать источником вдохновения для многих. 🌟
📡 А если у вас уже есть канал, пусть даже маленький – кидайте его в комментарии! Давайте поддерживать друг друга! 🌍🤗
  • 👍 24
  • ❤ 20
  • 👏 7
  • ❤‍🔥 5
  • 🖕 1
Post #226 3.05K
Подписчик прислал мне интересную задачку с 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)


Большое решение, но если по частям разобрать, то разобраться проще. Для этого вот вам ноутбук с этим скриптом. экспериментируйте!
Ну и всем отдыха на море в этом году! 🏖🏖🐠🌊
  • 🔥 16
  • ❤ 3
  • ❤‍🔥 3
  • 👌 1
Post #223 2.72K
🔥 Исследование рынка аналитиков 2024: полные результаты

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

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

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

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

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

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

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

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

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

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

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

📨 Пишите на почту data@new.hr
  • 🔥 9
  • ❤ 5
  • ⚡ 1
Post #222 2.13K
Подъехало исследование по 2024! Смотрим, изучаем, анализируем. 📈📊
Post #221 2.77K
👍 Решила задачку уровня 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. Кстати за прошлую неделю я выдала медали в нашем рейтинге. 🥇🥈🥉Заглядывайте и присоединяйтесь!
  • ❤ 17
  • 👍 14
  • ❤‍🔥 4
Post #217 2.49K
🏆 Кто будет первым в рейтинге?🏆
Я немного запустила нашу табличку мотивации… В том смысле, что сама исправно ставлю свои галочки ✔️, но вот новых мотивационных картинок уже больше недели никому не раздавала. И тут мне написали об этом – с сожалением!

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

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

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

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

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

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

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

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

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

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

P.S. Если вдруг пропустили, о чем вообще речь, вот тут и тут про наши мотивационные таблички. Заглядывайте — возможно, это как раз то, чего вам не хватало для продуктивности! 😉
  • ❤ 8
  • ❤‍🔥 3
Post #215 2.46K
Ребята, привет! 👋

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

🎁 Для вас есть 5% скидка – просто скажите, что вы «от Валерии / мира аналитики данных».
Это не реклама (она будет позже 😜), просто я сама иду на курс и зову вас с собой! 🚀
Telegram No Data No Growth | Pavel Bukhtik ❓ Все еще не хватает опыта в АБ? По многочисленным просьбам, 10 марта 2025 стартует третий поток моего практического курса по АБ тестированию. Изначально я его даже не планировал, но половина мест уже разобрана по предзаписи на сайте. В карточках выше ты…
  • 👍 6
  • ❤‍🔥 2
  • 🤣 2
  • ❤ 1
Post #213 2.85K
👍 Задачка с 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 и группировка, а также построить наглядный расчет метрик.

✅ Попробуйте сами — это отличная практика!
  • 👍 8
  • ❤‍🔥 3
  • 🔥 3
Post #211 3.14K
👍 Задачка с 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 дальше. ✨🚀
  • ❤ 40
  • 🔥 10
  • 🐳 6
  • ✍ 3
  • 👍 3
Post #209 3.36K
👨‍💻Принесла вам интересную задачку: нужно выяснить, кто из клиентов продлевает тариф (подписку для приложений например) без перерывов (в нашем условном примере перерыв — это больше 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 часто выручает, когда нужно сравнивать строки внутри «своей» группы. Надеюсь, было полезно!
  • ❤ 20
  • 👍 17
  • ❤‍🔥 7
Post #208 2.96K
🔥 Сегодня прочитала, что Сбербанк начал масштабные сокращения в IT-подразделении Ecom.tech (это «Купер», «Мегамаркет», «Сберлогистика» и «Самокат») — некоторые команды «урежут» до 50%! 😱

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

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

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

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

Короче нам надо учится, учиться и еще раз учиться.
Думаете сейчас будет реклама курсов? А вот и нет. 😜
https://rb.ru/news/sber-ecom-personnel/
  • 👍 15
  • ❤ 6
  • 😢 3
  • 😁 1
  • 💯 1
Post #207 3.01K
Друзья, вы просто космос! Посмотрите, сколько новых задач и участников появилось в наших таблицах: тут и курсы по аналитике, и чтение книг, и даже ежедневные тренировки и йога. Кажется, мы все дружно рванули вперёд! 🚀

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

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

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

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

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

Я продолжу следить за прогрессом — и, конечно, всегда вэлкам для новых идей! 💡💡💡
📎 Табличка тут - тык
  • ❤‍🔥 15
  • ❤ 2
Post #206 3.54K
🎯 Вот и пролетели каникулы. Не жалею, что не сидела за компом. Мы семьей ездили на дачу, парились в баньке, жгли камин, встречались с друзьями, ездили к бабушкам, побывали на Красной площади.

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

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

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

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

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

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

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

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

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

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

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

Скажу честно - после того как я это придумала, мне показалось, что возможно я зря это затеваю. Заходить, смотреть, самой отмечать свои занятия. Но это был искренний порыв помочь. Надеюсь эта инициатива реально окажется полезной!
Google Docs Трекер
  • 🔥 18
  • ❤ 10
  • 👍 7
Post #205 3.2K
🎄С наступающим Новым годом, друзья!🎄

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

В эти праздничные дни отложите гаджеты в сторону и уделите время своему телу: ощутите мир, двигайтесь, встречайтесь с друзьями и готовьте вкусные угощения! Позвольте себе отдохнуть от виртуальной суеты!
У меня в планах конечно салаты, дача и общение с близкими.

Мечтайте, загадывайте желания и смело идите к своим целям! 🔼🎆🎆🎆🎁✔️😀

До встречи в новом году! 🎄
  • ❤‍🔥 14
  • 🎄 5
  • ☃ 2
  • 🔥 1
Post #204 3.46K
🤪 Друзья, проведем анализ по результатам 2024.

Че там по метрикам в сравнении с 2023?

Подписчики: было 1762, стало 3753 — +113% (больше чем в 2 раза!)
Публикации: было 56, стало 94 — прирост +68%
Комментарии: с 461 до 492 — +7%
Пересылки: 730 → 964 — +32%
Реакции: 1.2K → 1.5K — +25%
Просмотры: 90.5K → 186.1K — +106%
Вывод: Канал вырос по сравнению с прошлым годом. 📈📊

🔥 Спасибо всем, кто комментирует, пересылает посты друзьям, кликает «нравится» и просто заглядывает на огонёк. Без вас такие результаты были бы невозможны! ❤️

Я подготовила список самых интересных публикаций за 2024 год:

🐍 Python и Pandas

✔️ Делим на группы: np.where() и loc против pd.cut (биннинг данных).

✔️Опять биннинг: как «нарезать» интервалы по 10 тыс. с помощью pd.cut и pd.interval_range.

✔️ Пример использования case в SQL, но и о питоне чуть — однако полезно заглянуть, как это в коде (часть публикации про Python-практику).

✔️ Как строить сводные таблицы методом pivot_table, заполнять пропуски и работать с fillna.

✔️ Шифрование телефонных номеров при помощи hashlib и встроенной hash()

✔️ Объединяем датафреймы так, чтобы сохранить порядок строк (пример с merge и сортировкой по изначальному индексу).

✔️Примеры кода: как сгруппировать данные и вывести их по аккаунтам (разбор рабочих задач).

✔️ Ищем idxmax внутри группировки, чтобы оставить строку с максимальным значением.

✔️ Сортировка и фильтрация: когда лучше использовать .iloc вместо .loc после группировок/срезов.

✔️ Анализ данных с регулярными выражениями в Python пример с re.findall

✔️«Хитрые задачки с работы» о том, как парсить и фильтровать ставки (процентные) без циклов в Python, используя регулярки, extractall и группировки: https://t.me/analysts_world/151 и https://t.me/analysts_world/154.

✔️ Проверка существования датафрейма в Python (через locals() или try-except).

✔️ Как считать сумму покупок по порядку (1-я, 2-я, 3-я) без оконных функций: groupby().cumcount() и т.д.

✔️ Пример с обёрткой SQL-запроса в Python-функцию (pandas + pandasql), чтобы гибко менять периоды выгрузки.

💾 SQL и базы данных
✔️ CASE в SQL, пример расчёта сумм с разными валютами (RUB/RUR).

✔️ Извлечение доменов почт клиентов (SUBSTRING_INDEX)

✔️Тестовое задание по SQL: две таблицы (отделы и персонал), примеры группировки и сравнения зарплаты сотрудника с зарплатой начальника.

✔️LEFT JOIN с условием в ON или в WHERE: объяснение, почему результаты могут отличаться.

✔️Хитрый приём для IN в SQL, если у вас в списке одно значение (добавляем фиктивный).

✔️Пример с обёрткой SQL-запроса в Python-функцию (pandas + pandasql), чтобы гибко менять периоды выгрузки.

🤔💭 Полезные мысли и карьера

✅ Как влиться в IT, если вы только начинаете; страхи, женские квоты. Статья с Хабра.

✅ Какой курс/обучение стоит выбрать, если планируете «войти» в IT. Советы по Excel, SQL и обретению опыта.

✅ Прокрастинация и личный баланс: про фитнес-клуб и необходимость отдыха.

✅ Баланс, фитнес, и почему нам нужно отдыхать.

✅«Красные маркеры» у работодателей и «красные флаги» у соискателей (пост о возрастных ограничениях и т.п.).

И хоть сегодня последний рабочий день, и, признаемся, учиться уже вряд ли хочется, всё же сохраните этот список — он пригодится, когда захочется прокачать скиллы после праздников. 🥳🎁😀🔔
  • 🔥 18
  • 👍 5
  • ❤ 2
Post #202 2.46K
🔥 200+ экспертов и каналов, за которыми следят аналитики

Делимся первыми инсайтами из исследования аналитиков, которое команда NEWHR провела в 2024 году. Это рейтинги и списки экспертов отрасли и каналов.

Выборка в исследовании получилась солидная — 1293 человека.

Вот кого опрошенные нами аналитики чаще всего отмечали в списке экспертов:
1. Анатолий Карпов
2. Валерий Бабушкин
3. Роман Бунин

А рейтинге каналов самыми известными оказались:
1. karpov.courses
2. Reveal the Data
3. настенька и графики

🔗 Изучить полные рейтинги и списки экспертов из исследования можно по ссылке.

💙 Мы благодарим наших информационных партнёров, которые помогли нам собрать такую внушительную выборку!

🎄 Команда NEWHR продолжает обрабатывать полные результаты исследования аналитиков: это данные о зарплатах, местах работы, желанных работодателях и многое другое. Мы опубликуем их в 2025 году. Следите за обновлениями!
  • ❤‍🔥 5
  • ✍ 5
  • ⚡ 1
  • 👍 1
Older posts →
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →