🔥 3 СПОСОБА ФИЛЬТРАЦИИ СТРОК ПЕРЕД АГРЕГИРОВАНИЕМ: SUBQUERY, COUNT + CASE, FILTER
ПРОЛОГ
Сгруппировать строки и посчитать какую-то метрику (например, сумму или среднее) - типичная операция в SQL. Мы знаем, что делается это с помощью оператора GROUP BY.
Однако иногда при расчетах нужно учитывать не все строки, а только удовлетворяющие некоторому условию. Давайте рассмотрим простейший пример.
Дана таблица users со столбцами:
* id
* name
* is_verified - подтвердил ли пользователь аккаунт (True/False)
* date_joined
Задача:
Посчитать количество подтвержденных пользователей, зарегистрировавшихся в сервисе в мае 2022 года, с разбивкой по дням.
* Кстати, работаем мы с PostgreSQL.
СПОСОБ 1. ПОДЗАПРОС.
Обычно все решают эту задачу с помощью подзапросов или CTE. То есть сначала выполняется фильтрация, а только затем агрегация и подсчет строк в новой таблице.
В нашем случае запрос будет выглядеть так:
* На большом количестве строк подзапрос потенциально загрузит в память миллионы строк
* Запрос довольно громоздкий для той задачи, что поставлена перед нами
СПОСОБ 2. COUNT + CASE
Классический прием для решения таких задач - использование оператора CASE внутри агрегатных функций. Ответ можно записать в таком виде:
«Фокус» в том, что внутри функции count мы считаем количество строк, которые удовлетворяют условию. Проверка условия осуществляется с помощью условного оператора CASE.
СПОСОБ 3. FILTER
Аналогичный результат агрегирования мы можем получить с помощью предложения FILTER. Механика действий у него аналогичная - на вход агрегатной функции count подаются только те строки, которые удовлетворяют условию фильтрации.
агрегатными функциями, когда они выступают в роли оконных.
- - - - - - - - - -
🔗 Освойте еще больше «фишечек» в нашем Симуляторе
ПРОЛОГ
Сгруппировать строки и посчитать какую-то метрику (например, сумму или среднее) - типичная операция в SQL. Мы знаем, что делается это с помощью оператора GROUP BY.
Однако иногда при расчетах нужно учитывать не все строки, а только удовлетворяющие некоторому условию. Давайте рассмотрим простейший пример.
Дана таблица users со столбцами:
* id
* name
* is_verified - подтвердил ли пользователь аккаунт (True/False)
* date_joined
Задача:
Посчитать количество подтвержденных пользователей, зарегистрировавшихся в сервисе в мае 2022 года, с разбивкой по дням.
* Кстати, работаем мы с PostgreSQL.
СПОСОБ 1. ПОДЗАПРОС.
Обычно все решают эту задачу с помощью подзапросов или CTE. То есть сначала выполняется фильтрация, а только затем агрегация и подсчет строк в новой таблице.
В нашем случае запрос будет выглядеть так:
with filtered_users as (Очевидные минусы такого подхода:
select
id,
is_active,
to_char(date_joined, 'DD') as "day"
from users
where is_active is True
and to_char(date_joined, 'YYYY-MM') = '2022-05'
)
select
day,
count(*) as cnt
from filtered_users
group by day
* На большом количестве строк подзапрос потенциально загрузит в память миллионы строк
* Запрос довольно громоздкий для той задачи, что поставлена перед нами
СПОСОБ 2. COUNT + CASE
Классический прием для решения таких задач - использование оператора CASE внутри агрегатных функций. Ответ можно записать в таком виде:
selectВидим, что запрос стал намного меньше + мы сразу же проводим все вычисления, не нагружая память.
to_char(date_joined, 'DD') as "day",
count(case when is_active is True then 1 end) as cnt
from users
where to_char(date_joined, 'YYYY-MM') = '2022-05'
group by "day"
«Фокус» в том, что внутри функции count мы считаем количество строк, которые удовлетворяют условию. Проверка условия осуществляется с помощью условного оператора CASE.
СПОСОБ 3. FILTER
Аналогичный результат агрегирования мы можем получить с помощью предложения FILTER. Механика действий у него аналогичная - на вход агрегатной функции count подаются только те строки, которые удовлетворяют условию фильтрации.
selectКстати, также удобно использовать filter с
to_char(date_joined, 'DD') as "day",
count(*) filter(where is_active is True) as cnt
from users
where to_char(date_joined, 'YYYY-MM') = '2022-05'
group by "day"
🔗 Освойте еще больше «фишечек» в нашем Симуляторе
👍24
🔥 Разбор тестового задания в Тиньков [SQL]
Итак, нам дана база клиентов, сотрудников и обзвонов (структура базы прикреплена ниже).
В какой СУБД мы будем работать — не сказано. По косвенным признакам мы предполагаем, что это PostgreSQL.
Задача 1.
Получить список сотрудников в формате:
Вывести: новое поле, назовем его
Эта задача достаточно простая — здесь даже нет необходимости джойнить другие таблицы, достаточно поработать с таблицей Employees.
Основная проблема — вывести ФИО через заданный разделитель. Многие решают эту задачу с помощью простой конкатенации:
Задача 2.
Вывести %% дозвона для каждого дня. Период с 01.10.2020 по текущий день.
%% дозвона – это доля принятых звонков (
Вывести:
Решение
Здесь задача уже поинтересней — мы все еще работаем с одной таблицей, но многие соискатели на таких задачах начинают городить многоэтажные подзапросы.
А на самом деле, все просто — достаточно просто знать, что условный оператор
Итак, чтобы посчитать
— посчитать кол-во звонков с
— разделить одно на другое
Давайте сделаем это в одном запросе, без подзапросов и
1. Почему мы написали не
2. Зачем мы делаем преобразование с помощью
Задача 3.
Дана таблица
-
-
Нужно написать запрос для расчета
Решение
Если что,
Многие по ошибке выводят
Соответственно, решение задачи сводится к следующим пунктам:
— посчитать количество уникальных клиентов за каждый месяц
— усреднить данные по всем месяцам
Для решения задачи мы будем использовать
- - - - -
🔗 Пройдите Симулятор по SQL, чтобы прокачаться на бизнесовых задачах 👉🏻 https://vk.cc/cfpuft
Итак, нам дана база клиентов, сотрудников и обзвонов (структура базы прикреплена ниже).
В какой СУБД мы будем работать — не сказано. По косвенным признакам мы предполагаем, что это PostgreSQL.
Задача 1.
Получить список сотрудников в формате:
«Иванова — Наталья – Юрьевна». ФИО должно быть прописано в одном столбике, разделение "—".Вывести: новое поле, назовем его
fio, birth_dt
РешениеЭта задача достаточно простая — здесь даже нет необходимости джойнить другие таблицы, достаточно поработать с таблицей Employees.
Основная проблема — вывести ФИО через заданный разделитель. Многие решают эту задачу с помощью простой конкатенации:
SELECTНо мы работаем в PostgreSQL, поэтому воспользуемся плюшкой — функцией
first_nm || '—' || middle_nm || '—' || last_nm AS fio,
birth_dt
FROM employees
CONCAT_WS. Она тоже делает конкатенацию строк, но первым аргументом принимает разделитель:SELECTВыглядит посимпатичней. Заодно и перед интервьюером блеснули знаниями 😅
concat_ws('—', first_nm, middle_nm, last_nm) AS fio,
birth_dt
FROM employees
Задача 2.
Вывести %% дозвона для каждого дня. Период с 01.10.2020 по текущий день.
%% дозвона – это доля принятых звонков (
dozv_flg = 1) от всех поступивших звонков (dozv_flg = 1 or dozv_flg = 0).Вывести:
date, sla (%% дозвона)Решение
Здесь задача уже поинтересней — мы все еще работаем с одной таблицей, но многие соискатели на таких задачах начинают городить многоэтажные подзапросы.
А на самом деле, все просто — достаточно просто знать, что условный оператор
CASE можно использовать внутри агрегатных функций — например, COUNT. Итак, чтобы посчитать
SLA, нам нужно:— посчитать кол-во звонков с
dozv_flg = 1
— посчитать общее количество звонков— разделить одно на другое
Давайте сделаем это в одном запросе, без подзапросов и
CTE. SELECTВот, собственно, и все. Но проговорим несколько важных моментов:
start_dttm::date AS "date",
COUNT(CASE
WHEN dozv_flg=1
THEN 1
END)/COUNT(CASE
WHEN dozv_flg IN (1, 0)
THEN 1
END) AS sla
FROM calls
WHERE start_dttm::date BETWEEN '2020-10-01' AND now()::date
GROUP BY start_dttm::date
1. Почему мы написали не
COUNT(*), а COUNT(CASE WHEN dozv_flg IN (1, 0) THEN 1 END)? Мы просто перестраховались — вдруг там еще какие-то значения могут быть. 2. Зачем мы делаем преобразование с помощью
::date? А потому что оператор between потеряет все записи за сегодня, если не преобразовать эти поля в дату. Опять же мы просто перестраховались. Задача 3.
Дана таблица
clients:-
id клиента-
calendar_at - дата входа в мобильное приложениеНужно написать запрос для расчета
MAU. Решение
Если что,
MAU - monthly active users: количество уникальных клиентов, проявляющих активность в приложении в течение месяца. Многие по ошибке выводят
MAU в виде таблицы со столбцами Месяц — Кол-во активных клиентов. Это неправильно - MAU всегда должно быть одним числом. Соответственно, решение задачи сводится к следующим пунктам:
— посчитать количество уникальных клиентов за каждый месяц
— усреднить данные по всем месяцам
Для решения задачи мы будем использовать
CTE и оператор DISTINCT внутри COUNT:WITH a AS(Сразу отметим -
SELECT to_char(calendar_dt, 'MM') AS mon,
COUNT(distinct id) AS cnt
FROM clients
GROUP BY mon)
SELECT avg(cnt) AS mau
FROM a
MAU можно считать и по-другому. Например, сразу брать цифры на примере одного месяца; находить медиану или как-то еще. Мы просто показали один из вариантов.- - - - -
🔗 Пройдите Симулятор по SQL, чтобы прокачаться на бизнесовых задачах 👉🏻 https://vk.cc/cfpuft
🔥12👍9
🔥 Транспонируем матрицу в одну строку в Python
Типичная задача: дана матрица
Как это сделать, подробно рассказываем тут 👉🏻 itresume.ru/problems/transp-matrix 👈🏻 (здесь же можно попробовать решить задачу)
Кстати, недавно видели такую задачу на собеседовании в известную компанию. А вы бы смогли решить? 😏
Типичная задача: дана матрица
[[1, 2, 3], [1, 2, 3]]. Необходимо ее транспонировать в одну строку → [[1, 1], [2, 2], [3, 3]]. Как это сделать, подробно рассказываем тут 👉🏻 itresume.ru/problems/transp-matrix 👈🏻 (здесь же можно попробовать решить задачу)
Кстати, недавно видели такую задачу на собеседовании в известную компанию. А вы бы смогли решить? 😏
🔥6👍1
Очень часто встречаемся у студентов с ошибкой деления целых чисел. В связи с чем - опрос. Проверим, сколько людей знает правильный ответ 🙃
- - - - -
Какой будет результат следующего запроса в PostgreSQL?
select 1/2
- - - - - P.S. Вечером будет разбор, не пропустите 😉
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7
🔥6
🔥 Деление целых чисел в PostgreSQL
Когда мы делим одно целое число на другое, мы всегда ожидаем увидеть правильный результат - даже если он дробный. Однако, в PostgreSQL это работает не так.
Простой пример:
Все очень просто - по умолчанию, в PostgreSQL деление целых чисел друг на друга дает также целое число:
Если говорить про практическую составляющую - это может негативно сказаться при расчете маржинальности, например:
Как быть?
Что делать и как избежать этой неприятной ошибки?
Очень просто - достаточно преобразовать числитель или знаменатель к дробному числу. Вот несколько способов:
* Умножить на дробное число (например,
* Выполнить явное преобразование типов с помощью
- - - - -
🔗 Еще больше фишечек вы узнаете в нашем Симуляторе по SQL 👉🏻 https://vk.cc/cfT9wd
Когда мы делим одно целое число на другое, мы всегда ожидаем увидеть правильный результат - даже если он дробный. Однако, в PostgreSQL это работает не так.
Простой пример:
select 1/2В чем подвох?
# 0
Все очень просто - по умолчанию, в PostgreSQL деление целых чисел друг на друга дает также целое число:
select pg_typeof(1/2)А в реальности это встречается?
# integer
Если говорить про практическую составляющую - это может негативно сказаться при расчете маржинальности, например:
select revenue/costЗдесь и доход (
# 0
revenue), и розничная цена (cost) представлены целыми числами, а маржинальность предполагается менее 100%. Как быть?
Что делать и как избежать этой неприятной ошибки?
Очень просто - достаточно преобразовать числитель или знаменатель к дробному числу. Вот несколько способов:
* Умножить на дробное число (например,
1.0)* Выполнить явное преобразование типов с помощью
cast
* Выполнить преобразование типов с помощью ::
select 1*1.0/2Мы обычно используем первый или третий варианты, т.к. второй просто объемней.
# 0.5
select cast(1 as numeric)/2
# 0.5
select 1::numeric/2
# 0.5
- - - - -
🔗 Еще больше фишечек вы узнаете в нашем Симуляторе по SQL 👉🏻 https://vk.cc/cfT9wd
🔥19👍6
🔥 Использование метода get в Python
Наверняка вы знаете, что из словаря в Python элемент можно «вытащить» минимум 2 способами:
* указав ключ в квадратных скобках (d[key])
* воспользовавшись методом get
Однако, очень часто на code review встречаемся с тем, что люди используют его неправильно, сами того не замечая. Поэтому - опрос 📊
Что выведет следующий код?
Наверняка вы знаете, что из словаря в Python элемент можно «вытащить» минимум 2 способами:
* указав ключ в квадратных скобках (d[key])
* воспользовавшись методом get
Однако, очень часто на code review встречаемся с тем, что люди используют его неправильно, сами того не замечая. Поэтому - опрос 📊
Что выведет следующий код?
d = {
'first': 1,
'second': 2
}
d.get('third', default=10)
P.S. Вечером будет подробный разбор - не пропустите 😉🔥5👍1😁1
😱13🔥6👍1
🔥 Использование метода get в Python
Итак, опрос показал, что только 23% опрошенных дали правильные ответы 😱 Давайте разбираться, что к чему.
# Зачем нужен get?
В комментариях нас спросили: «А зачем вообще нужен метод get?». Основных причины 2:
1. Если указать в квадратных скобках ключ, которого нет в словаре, мы получим
2. Если мы хотим указать какое-то дефолтное значение, которое будет использоваться по умолчанию в случае отсутствия ключа, нам придется писать лишний код. Например:
Решение есть! Это метод
* Не кидает ошибку, если ключ не найден
* Позволяет задать значение по умолчанию (указывается вторым аргументом)
Например, получаем не
# В чем же ошибка?
Казалось бы, мы делаем все логично - вторым аргументом указываем дефолтное значение
А ошибка весьма нетривиальная: Метод get не принимает именованные аргументы!
Соответственно, когда мы пишем такой код, мы ожидаемо получаем
# Как быть?
Все очень просто - достаточно убрать имя аргумента и просто указать значение по умолчанию вторым аргументом:
Вот такое неожиданное поведение. Согласитесь - легко попасть в эту ловушку... 🥲
- - - - -
🔗 Прокачивайтесь в Python и других языках на интересных задачах с платформой itresume.ru
Итак, опрос показал, что только 23% опрошенных дали правильные ответы 😱 Давайте разбираться, что к чему.
# Зачем нужен get?
В комментариях нас спросили: «А зачем вообще нужен метод get?». Основных причины 2:
1. Если указать в квадратных скобках ключ, которого нет в словаре, мы получим
KeyError. Например:d = {
'first': 1,
'second': 2
}
d['third']
# KeyError: 'third'2. Если мы хотим указать какое-то дефолтное значение, которое будет использоваться по умолчанию в случае отсутствия ключа, нам придется писать лишний код. Например:
try:
value = d['third']
except KeyError:
value = 10
print(value)
# 10
Решение есть! Это метод
get, который:* Не кидает ошибку, если ключ не найден
* Позволяет задать значение по умолчанию (указывается вторым аргументом)
Например, получаем не
KeyError, а None, хотя такого ключа в исходном словаре d нет:d.get('third')
# None# В чем же ошибка?
Казалось бы, мы делаем все логично - вторым аргументом указываем дефолтное значение
default=10. Что не так? 🧐А ошибка весьма нетривиальная: Метод get не принимает именованные аргументы!
Соответственно, когда мы пишем такой код, мы ожидаемо получаем
TypeError:d.get('third', default=10)
# TypeError: get() takes no keyword arguments# Как быть?
Все очень просто - достаточно убрать имя аргумента и просто указать значение по умолчанию вторым аргументом:
d.get('third', 10)
# 10Вот такое неожиданное поведение. Согласитесь - легко попасть в эту ловушку... 🥲
- - - - -
🔗 Прокачивайтесь в Python и других языках на интересных задачах с платформой itresume.ru
🔥18👍10😱3👎2
😱 Будьте аккуратны с последовательностью JOIN в SQL-запросах
Проверяя работы студентов в нашем Симуляторе, мы постоянно сталкиваемся с одной и той же ошибкой:
Люди пренебрегают порядком джоинов в запросе, что ведет к неправильному результату и даже потере данных!
Приведем пример для иллюстрации этой ошибки. Пусть нам даны 3 таблицы:
* Таблица с задачами Problem
* Таблица с тегами TagList
* Таблица со страницами сайта Page
* Таблица-связка задач и тегов ProblemTag
А теперь давайте попробуем написать 2 запроса:
1. Выведем все задачи со всеми соответствующими каждой задаче тегами, а также информацию о странице по каждой задаче
2. Выведем все задачи со всеми соответствующими тегами, а также информацию по каждому тегу
Допустим первый запрос мы написали так:
По идее, учитывая поставленное задание, количество строк в этих двух запросах должно совпадать. Это логично - в обоих запросах мы отталкиваемся от таблиц
Если мы посмотрим на количество строк, то заметим, что во втором запросе мы потеряли строки. Вот так выглядит количество строк:
🟢 Как так получилось?
Очень просто - во всем виновата последовательность джоинов:
1. В первом запросе с помощью
2. А во втором запросе последний джоин отбрасывает все задачи без тегов! Это происходит потому что в
Получается, во втором запросе
🟢 Как исправить?
Есть несколько способов исправить такой запрос:
1. Изменить порядок джоинов (перенести
2. Вместо последнего
- - - - -
🔗 Залетайте в Симулятор «Аналитик данных» 👉🏻 https://vk.cc/ch76dC и не делайте таких ошибок 🙃
Проверяя работы студентов в нашем Симуляторе, мы постоянно сталкиваемся с одной и той же ошибкой:
Люди пренебрегают порядком джоинов в запросе, что ведет к неправильному результату и даже потере данных!
Приведем пример для иллюстрации этой ошибки. Пусть нам даны 3 таблицы:
* Таблица с задачами Problem
* Таблица с тегами TagList
* Таблица со страницами сайта Page
* Таблица-связка задач и тегов ProblemTag
А теперь давайте попробуем написать 2 запроса:
1. Выведем все задачи со всеми соответствующими каждой задаче тегами, а также информацию о странице по каждой задаче
2. Выведем все задачи со всеми соответствующими тегами, а также информацию по каждому тегу
Допустим первый запрос мы написали так:
select *А второй запрос так:
from problem p
left join problemtag p2
on p.id = p2.problem_id
join page p3
on p.page_id = p3.id
select *🟢 А в чем, собственно, ошибка?
from problem p
left join problemtag p2
on p.id = p2.problem_id
join taglist t
on t.id = p2.tag_id
По идее, учитывая поставленное задание, количество строк в этих двух запросах должно совпадать. Это логично - в обоих запросах мы отталкиваемся от таблиц
Problem и ProblemTag, а меняется только последний джоин. Однако, именно он и является критичным.Если мы посмотрим на количество строк, то заметим, что во втором запросе мы потеряли строки. Вот так выглядит количество строк:
В первом запросе - 524И вот теперь мы видим, что во втором запросе мы потеряли ровно все задачи, для которых нет ни одного тега!
Во втором запросе - 451
В таблице ProblemTag - 451
Задач, для которых нет ни одного тега - 73
🟢 Как так получилось?
Очень просто - во всем виновата последовательность джоинов:
1. В первом запросе с помощью
left join мы сохраняем все задачи, даже если для них нет тегов. А последний джоин эти задачи не отсеивает, потому что соединяет таблицы Page и Problem, для которых есть соответствие в каждой строке. 2. А во втором запросе последний джоин отбрасывает все задачи без тегов! Это происходит потому что в
join фигурирует таблица ProblemTag. Т.к. джоин обычный (inner join), остаются только строки из ProblemTag, а значит все задачи, для которых нет тегов просто выкидываются из расчета. Получается, во втором запросе
left join не имеет никакого смысла и его эффект перебивается последним join? Да, именно так. И это очень частая ошибка, которая встречается во многих боевых задачах. А самое страшное, что ее реально сложно заметить. 🟢 Как исправить?
Есть несколько способов исправить такой запрос:
1. Изменить порядок джоинов (перенести
left на последнее место и заменить на right)2. Вместо последнего
inner join также указать left join
Например:select *А вы допускали такую ошибку? На всякий случай проверьте свои рабочие скрипты, вдруг туда затесался враг 😁
from problemtag p
join taglist t
on t.id = p.tag_id
right join problem p2
on p2.id = p.problem_id
- - - - -
🔗 Залетайте в Симулятор «Аналитик данных» 👉🏻 https://vk.cc/ch76dC и не делайте таких ошибок 🙃
👍9🔥4
🔥 Давайте проведем live coding?
Ребят, у нас возникла идея - а давайте покодим в прямом эфире? Например, решим какое-нибудь тестовое задание по SQL или Python на позицию Аналитика Данных 🙃
🟢 Если вам нравится эта мысль - поставьте, пожалуйста, реакцию на это сообщение. Так мы поймем, что интерес есть и в ближайшее время вернемся с приглашением 🤟🏻
P.S. Если вы хотите другую тему для лайвкодинга - напишите об этом в комментариях. Мы с удовольствием возьмем ее в работу.
P.P.S. Если у вас есть классное тестовое задание, которые было бы круто порешать в прямом эфире - напишите в личку @andron233
Ребят, у нас возникла идея - а давайте покодим в прямом эфире? Например, решим какое-нибудь тестовое задание по SQL или Python на позицию Аналитика Данных 🙃
🟢 Если вам нравится эта мысль - поставьте, пожалуйста, реакцию на это сообщение. Так мы поймем, что интерес есть и в ближайшее время вернемся с приглашением 🤟🏻
P.S. Если вы хотите другую тему для лайвкодинга - напишите об этом в комментариях. Мы с удовольствием возьмем ее в работу.
P.P.S. Если у вас есть классное тестовое задание, которые было бы круто порешать в прямом эфире - напишите в личку @andron233
🔥108👍33
🔥 Лайвкодинг: «Ща порешаем» в новом Симуляторе «Аналитик данных» с Глебом Михайловым
Недавно мы предложили провести лайвкодинг и вы с энтузиазмом восприняли эту идею.
Поэтому мы решили сделать даже круче:мы дали Глебу Михайлову (кто ж не знает Глеба) доступ к одной главе нашего нового Симулятора «Аналитик данных ».
📌 В воскресенье в 19:00 МСК приходите на стрим - Глеб будет делать распаковку симулятора и решать топовые бизнесовые задачи на SQL.
Кстати, крутой подгон - мы также дадим каждому участнику доступ к главе и к задачам: сможете кодить вместе с Глебом 🤟🏻
Короче, ждем всех в воскресенье в 19:00 - будет классно. Посмотрим, сможет ли Глеб симулировать аналитика данных 😈😂
Недавно мы предложили провести лайвкодинг и вы с энтузиазмом восприняли эту идею.
Поэтому мы решили сделать даже круче:
Кстати, крутой подгон - мы также дадим каждому участнику доступ к главе и к задачам: сможете кодить вместе с Глебом 🤟🏻
Короче, ждем всех в воскресенье в 19:00 - будет классно. Посмотрим, сможет ли Глеб симулировать аналитика данных 😈😂
👍18🔥8🎉3
🔥 Начинаем лайвкодить SQL через 5 минут
Это напоминалка о том, что через 5 минут мы начинаем стрим с Глебом. Будем решать крутые задачки по SQL в рамках нашего нового Симулятора «Аналитик данных».
🔗 Ссылка на стрим: https://youtu.be/2jDFud5hRHM. Подключайтесь, будет круто!
Хотите решать вместе с нами? Вот вам ссылочка на Главу 6 «Группировки и агрегации», которую и будет проходить Глеб 👉🏻 https://lms.simulative.ru/gleb/6/1/leopard
А если хотите залететь в Симулятор по выгодной цене - то просто введите промокод dataleopard15 на сайте, он даст вам 15% скидки 😏
Это напоминалка о том, что через 5 минут мы начинаем стрим с Глебом. Будем решать крутые задачки по SQL в рамках нашего нового Симулятора «Аналитик данных».
🔗 Ссылка на стрим: https://youtu.be/2jDFud5hRHM. Подключайтесь, будет круто!
Хотите решать вместе с нами? Вот вам ссылочка на Главу 6 «Группировки и агрегации», которую и будет проходить Глеб 👉🏻 https://lms.simulative.ru/gleb/6/1/leopard
А если хотите залететь в Симулятор по выгодной цене - то просто введите промокод dataleopard15 на сайте, он даст вам 15% скидки 😏
👍5❤3
🔥 Долой длинные строки в Python
Во время код-ревью мы часто сталкиваемся с длинными строками кода, которые даже не влезают в экран. И казалось бы - они содержат настолько «стройную» информацию, что даже не знаешь, где (и зачем) поставить перенос на следующую строку.
Вот несколько случаев, где это встречается особенно часто:
* Длинные строки
* Большое количество аргументов в функции
* `method chaining` в Pandas
Рассмотрим такой «длинный» код на примере Pandas. Согласитесь, выглядит жутко:
df = coderun[coderun["cohort"] >= "2022-01"].groupby(["cohort", "language", "user_id"])["problem_id"].agg("nunique").groupby(["cohort", "language"]).agg(np.mean).reset_index().pivot_table(values="problem_id", columns=["language"], index=["cohort"])
А теперь давайте приведем код в порядок. Есть, как минимум, два метода борьбы с такими ситуациями.
🔵 Перенос строки с помощью обратного слеша
Достаточно поставить в конце строки обратный слеш и Python будет воспринимать весь написанный код как единую строку.
df = coderun[coderun["cohort"] >= "2022-01"] \
.groupby(["cohort", "language", "user_id"])["problem_id"] \
.agg("nunique") \
.groupby(["cohort", "language"]) \
.agg(np.mean) \
.reset_index() \
.pivot_table(values="problem_id", columns=["language"], index=["cohort"]
Сами видите - код стал в разы более читаемым и даже компактным.
🔵 Оборачивание круглыми скобками
Прием заключается в том, что мы просто оборачиваем все выражение в круглые скобки и это тоже рассматривается Python как одна строка кода.
df = (
coderun[coderun['cohort'] >= '2022-01']
.groupby(['cohort', 'language', 'user_id'])['problem_id']
.agg('nunique')
.groupby(['cohort', 'language'])
.agg(np.mean)
.reset_index()
.pivot_table(values='problem_id', columns=['language'], index=['cohort'])
)
На наш взгляд, этот вариант даже лучше - нет лишних символов и код выглядит еще более аккуратным.
- - - - -
Кстати, а вы знали про method chaining в Pandas и про способы переноса строк?
Во время код-ревью мы часто сталкиваемся с длинными строками кода, которые даже не влезают в экран. И казалось бы - они содержат настолько «стройную» информацию, что даже не знаешь, где (и зачем) поставить перенос на следующую строку.
Вот несколько случаев, где это встречается особенно часто:
* Длинные строки
* Большое количество аргументов в функции
* `method chaining` в Pandas
Рассмотрим такой «длинный» код на примере Pandas. Согласитесь, выглядит жутко:
df = coderun[coderun["cohort"] >= "2022-01"].groupby(["cohort", "language", "user_id"])["problem_id"].agg("nunique").groupby(["cohort", "language"]).agg(np.mean).reset_index().pivot_table(values="problem_id", columns=["language"], index=["cohort"])
А теперь давайте приведем код в порядок. Есть, как минимум, два метода борьбы с такими ситуациями.
🔵 Перенос строки с помощью обратного слеша
Достаточно поставить в конце строки обратный слеш и Python будет воспринимать весь написанный код как единую строку.
df = coderun[coderun["cohort"] >= "2022-01"] \
.groupby(["cohort", "language", "user_id"])["problem_id"] \
.agg("nunique") \
.groupby(["cohort", "language"]) \
.agg(np.mean) \
.reset_index() \
.pivot_table(values="problem_id", columns=["language"], index=["cohort"]
Сами видите - код стал в разы более читаемым и даже компактным.
🔵 Оборачивание круглыми скобками
Прием заключается в том, что мы просто оборачиваем все выражение в круглые скобки и это тоже рассматривается Python как одна строка кода.
df = (
coderun[coderun['cohort'] >= '2022-01']
.groupby(['cohort', 'language', 'user_id'])['problem_id']
.agg('nunique')
.groupby(['cohort', 'language'])
.agg(np.mean)
.reset_index()
.pivot_table(values='problem_id', columns=['language'], index=['cohort'])
)
На наш взгляд, этот вариант даже лучше - нет лишних символов и код выглядит еще более аккуратным.
- - - - -
Кстати, а вы знали про method chaining в Pandas и про способы переноса строк?
🔥24👍3
🔥 Ищем технического редактора (автора контента) к себе в команду
Друзья, мы расширяем команду и ищем человека, который будет помогать нам с контентом во всем его многообразии. Естественно, все на 100% связано с программированием и аналитикой. Вот примеры задач:
* создавать задачи и тесты для нас и наших корпоративных клиентов
* создавать посты в соцсети
* создавать обучающие материалы, пособия, шпаргалки и т.д.
Если вам это интересно - почитать про вакансию можно по ссылке (там же небольшое тестовое):
🔗 ссылка на вакансию
Работа очень интересная и масштабная - каждую единицу созданного вами контента будут видеть и использовать тысячи людей 🔥 Будем ждать вас в нашу команду 🙂
P.S. Идеального знания языков программирования не требуется.
- - - - -
А если эта вакансия может быть интересна вашим друзьям/родственникам/коллегам - обязательно перешлите им, пожалуйста.
Друзья, мы расширяем команду и ищем человека, который будет помогать нам с контентом во всем его многообразии. Естественно, все на 100% связано с программированием и аналитикой. Вот примеры задач:
* создавать задачи и тесты для нас и наших корпоративных клиентов
* создавать посты в соцсети
* создавать обучающие материалы, пособия, шпаргалки и т.д.
Если вам это интересно - почитать про вакансию можно по ссылке (там же небольшое тестовое):
🔗 ссылка на вакансию
Работа очень интересная и масштабная - каждую единицу созданного вами контента будут видеть и использовать тысячи людей 🔥 Будем ждать вас в нашу команду 🙂
P.S. Идеального знания языков программирования не требуется.
- - - - -
А если эта вакансия может быть интересна вашим друзьям/родственникам/коллегам - обязательно перешлите им, пожалуйста.
👍5❤1
🔥 Агрегирование в Pandas, которым вы не пользовались раньше (наверняка)
Работая с библиотекой
Но сегодня нам хотелось бы рассказать об одной интересной функции, которую можно использовать в агрегации. Речь пойдёт о функции
Более наглядно рассмотрим работу функции на небольшом примере. Представим, что у вас есть датафрейм с
- - - - - - - - - -
🔗 Хотите прокачаться в аналитике? Ждем вас в Симуляторе «Аналитик данных» →
Работая с библиотекой
Pandas, нередко приходится применять функции группировки и агрегирования. Все мы привыкли к sum, count и прочим распространенным функциям.Но сегодня нам хотелось бы рассказать об одной интересной функции, которую можно использовать в агрегации. Речь пойдёт о функции
set. Она позволит вывести уникальное множество значений для каждой группы.Более наглядно рассмотрим работу функции на небольшом примере. Представим, что у вас есть датафрейм с
id клиента и с наименованием его покупки:| id | product |Для отображения уникальных покупок каждого клиента воспользуемся такой конструкцией:
|----|---------|
| 1 | p1 |
| 2 | p2 |
| 1 | p3 |
df.groupby('id').agg({'product': set})
В результате мы получим таблицу:| id | product |А какими способами вы бы решили данную задачу? 😏
|----|----------|
| 1 | {p1, p3} |
| 2 | {p2} |
- - - - - - - - - -
🔗 Хотите прокачаться в аналитике? Ждем вас в Симуляторе «Аналитик данных» →
🔥26
🔥 Можно ли обойтись без OFFSET в SQL?
Команда
Но что делать, если необходимо вывести строки, начиная со второй? Скорее всего, вы воспользуетесь командой
Однако, так же можно решить эту задачу следующей конструкцией:
⛔️ Обратите внимание, что такой способ работает не во всех СУБД!
Если в MySQL можно написать такой запрос, то в PostgreSQL он выдаст ошибку и придётся воспользоваться командой
- - - - - - - - - -
🔗 Хотите прокачать свой SQL? Заходите решать задачки на платформу IT Resume →
Команда
LIMIT позволяет вывести ограниченное количество записей из таблицы. Например:SELECT * FROM tableДанный запрос выведет первые 10 строк из таблицы.
LIMIT 10
Но что делать, если необходимо вывести строки, начиная со второй? Скорее всего, вы воспользуетесь командой
OFFSET, и это будет верным решением.Однако, так же можно решить эту задачу следующей конструкцией:
SELECT * FROM tableКоманда LIMIT отсекает 1 строку и берет следующие 10, которые идут после неё.
LIMIT 1, 10
⛔️ Обратите внимание, что такой способ работает не во всех СУБД!
Если в MySQL можно написать такой запрос, то в PostgreSQL он выдаст ошибку и придётся воспользоваться командой
OFFSET. А в MSSQL так и вовсе нет оператора LIMIT, в этой СУБД используют команду TOP.- - - - - - - - - -
🔗 Хотите прокачать свой SQL? Заходите решать задачки на платформу IT Resume →
🔥16👍2
🔥 Метрика N-day Retention - важнейшая метрика продукта
Если вы работали с продуктовой аналитикой, вы наверняка слышали о метрике
Мы решили подготовить для вас небольшие шпаргалки по каждому виду
Данная метрика является одной из основных. Мало привлечь внимание клиентов к своему продукту, важно ещё и удержать как можно большее количество пользователей.
Рассмотрим как рассчитать
1 сентября 100 человек познакомились с нашим продуктом (например, установили приложение). Мы решили посчитать
В итоге, чем выше значение n-day Retention, тем меньше отток клиентов.
P.S. стоит так же обратить внимание на специфику продукта. К примеру приложение по поиску авиабилетов будет иметь значение данной метрики ниже, чем соцсеть.
- - - - - - - - - -
🔗 Хотите научиться считать не только n-day, но и другие виды retention в SQL, Excel и не только? Приходите в симулятор “Аналитик данных”!
Если вы работали с продуктовой аналитикой, вы наверняка слышали о метрике
Retention. Но знаете ли вы, что есть несколько видов данной метрики? Мы решили подготовить для вас небольшие шпаргалки по каждому виду
Retention. Начнём, пожалуй, с классической метрики. N-day Retention - метрика, которая показывает, какой процент клиентов продолжает пользоваться продуктом в конкретный день после знакомства.Данная метрика является одной из основных. Мало привлечь внимание клиентов к своему продукту, важно ещё и удержать как можно большее количество пользователей.
Рассмотрим как рассчитать
n-day Retention на примере.1 сентября 100 человек познакомились с нашим продуктом (например, установили приложение). Мы решили посчитать
n-day Retention седьмого дня. Считаем количество пользователей, которые воспользовались приложением 8 сентября, т.е. спустя 7 дней со дня установки. Таких клиентов оказалось 37. Находим долю этих клиентов:(37 / 100) * 100% = 37%То есть мы удержали 37% новых пользователей. Это и есть
n-day Retention на седьмой день.В итоге, чем выше значение n-day Retention, тем меньше отток клиентов.
P.S. стоит так же обратить внимание на специфику продукта. К примеру приложение по поиску авиабилетов будет иметь значение данной метрики ниже, чем соцсеть.
- - - - - - - - - -
🔗 Хотите научиться считать не только n-day, но и другие виды retention в SQL, Excel и не только? Приходите в симулятор “Аналитик данных”!
🔥9👍1
🔥 Лайфхак: работа с датами в связке Excel - Python
Нередко возникают моменты, когда при создании датафрейма на основе
Рассмотрим, например, дату
Для получения даты в числовом виде в
И как же быть в таких ситуациях? На помощь приходит библиотека
Переведём число 44571 в дату используя конструкцию ниже:
- - - - - - - - - -
🔗 Приходите к нам на платформу, у нас есть интересные задачи на Python и не только: IT Resume
Нередко возникают моменты, когда при создании датафрейма на основе
Excel файла, даты записываются в различных форматах. Сегодня нам бы хотелось рассмотреть случай, когда дата имеет числовой формат.Рассмотрим, например, дату
10.01.2022. Если преобразовать её в число в Excel, мы получим 44571, а в Python - 738165. Для получения даты в числовом виде в
Python мы использовали такую конструкцию:import datetimeПочему так происходит? Дело в том, что
datetime.date(2022, 1, 10).toordinal()
# 738165
Excel начинает отсчёт с 1900 года, а Python с 1 года.И как же быть в таких ситуациях? На помощь приходит библиотека
xlrd.Переведём число 44571 в дату используя конструкцию ниже:
from xlrd.xldate import xldate_as_datetimeБраво! Вы великолепны! Вот так с помощью двух строчек можно преобразовать даты к одному формату!
print(xldate_as_datetime(44571, 0))
# 2022 - 01 - 10 00:00:00
- - - - - - - - - -
🔗 Приходите к нам на платформу, у нас есть интересные задачи на Python и не только: IT Resume
👍10🔥4🎉1
🔥 Ищем технического редактора (автора контента) к себе в команду
Друзья, мы расширяем команду и ищем человека, который будет помогать нам с контентом во всем его многообразии. Естественно, все на 100% связано с программированием и аналитикой. Вот примеры задач:
* создавать задачи и тесты для нас и наших корпоративных клиентов
* создавать посты в соцсети
* создавать обучающие материалы, пособия, шпаргалки и т.д.
Если вам это интересно - почитать про вакансию можно по ссылке (там же небольшое тестовое):
🔗 ссылка на вакансию
Работа очень интересная и масштабная - каждую единицу созданного вами контента будут видеть и использовать тысячи людей 🔥 Будем ждать вас в нашу команду 🙂
P.S. Идеального знания языков программирования не требуется.
- - - - -
А если эта вакансия может быть интересна вашим друзьям/родственникам/коллегам - обязательно перешлите им, пожалуйста.
Друзья, мы расширяем команду и ищем человека, который будет помогать нам с контентом во всем его многообразии. Естественно, все на 100% связано с программированием и аналитикой. Вот примеры задач:
* создавать задачи и тесты для нас и наших корпоративных клиентов
* создавать посты в соцсети
* создавать обучающие материалы, пособия, шпаргалки и т.д.
Если вам это интересно - почитать про вакансию можно по ссылке (там же небольшое тестовое):
🔗 ссылка на вакансию
Работа очень интересная и масштабная - каждую единицу созданного вами контента будут видеть и использовать тысячи людей 🔥 Будем ждать вас в нашу команду 🙂
P.S. Идеального знания языков программирования не требуется.
- - - - -
А если эта вакансия может быть интересна вашим друзьям/родственникам/коллегам - обязательно перешлите им, пожалуйста.
🔥6❤1👍1