Forwarded from Data jobs — вакансии по data science, анализу данных, аналитике, искусственному интеллекту
👨🏻💻 Младший аналитик данных
SMS Traffic — является крупным игроком на рынке коммуникации компаний и клиентов, при помощи различных каналов связи, ищет младшего аналитика данных
Что почём?
▪️Junior
▪️До 100 000 ₽
▪️Офис (Москва)
📩 Изучить вакансию
SMS Traffic — является крупным игроком на рынке коммуникации компаний и клиентов, при помощи различных каналов связи, ищет младшего аналитика данных
Что почём?
▪️Junior
▪️До 100 000 ₽
▪️Офис (Москва)
📩 Изучить вакансию
hh.ru
Вакансия Младший аналитик данных в Москве, работа в компании SMS Traffic (вакансия в архиве c 29 августа 2023)
Зарплата: до 100000 ₽ за месяц. Москва. Требуемый опыт: 1–3 года. Занятость: полная. Дата публикации: 14.08.2023.
❤8
Очень интересно и много полезной практики:
✔️ Как быстро прокачаться в настройке систем веб-аналитики?
✔️ Что влияет на размер выборки и длительность АБ теста?
✔️ Как прокачать скилл аналитика?
Хороших каналов мало не бывает
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
Борзило
⇨ Про аналитику, продукты, маркетинг
⇨ Автор курса по АБ тестам
⇨ Смело пиши - @borzilo_y
ИНН 026702638983
⇨ Автор курса по АБ тестам
⇨ Смело пиши - @borzilo_y
ИНН 026702638983
🤩10❤1
👀 Розыск регулярных выражений
⁉️ Озадачили тут меня недавно запросом. Реально ли найти клиентов (account_id) у которых более 70% пользователей с именами на латинице.
- Конечно реально, - ответила я и приняласьвспоминать гуглить регулярные выражения. Регулярка- это некий шаблон, по которому фильтруется текст. В Python для работы с регулярными выражениями используют модуль re.
^ - Соответствует началу строки.
[a-zA-Z] — любая буква на латинице в нижнем и верхнем регистре;
[0-9] — любая цифра от нуля до девяти
🔹 Как пример:
import re
s = "Yelena_Shon"
search = re.search(r'[a-zA-Z0-9]', s)
print(search)
Код выдаст <_sre.SRE_Match object; span=(0, 1), match='Y'>
🔹Еще вариант:
s = "Иван Петров"
search = re.search(r'[a-zA-Z0-9]', s)
print(search)
А этот код выдаст None
Но нам нужно как-то это применить в датафрейме, а не просто к строке, поэтому воспользуемся в дальнейшем apply.
🔥 Итак, я выкачала юзеров в датафрейм all_users со столбцами account_id, user_id, full_name.
Создадим столбец 'check_name', в котором будем записывать результат проверки
all_users['check_name']= all_users['full_name'].apply(lambda x: re.search(r'^[a-zA-Z0-9]',str(x))).fillna(0)
Затем отбираем там, где не ноль, чтобы потом посчитать юзеров написанных на латинице
all_eng_users = all_users[all_users['check_name']!=0]
Делаем группировку по аккаунтам c подсчетом количества пользователей (user_id) и создаем датафрейм count_eng_users. В нем будет две колонки: номера клиента-account_id и кол-во пользователей, написанных на латинице:
count_eng_users = all_eng_users.groupby('account_id', as_index = False).agg({'user_id':'count'}).rename(columns ={'user_id':'eng_count_users'})
Теперь то же самое сделаем, чтобы подсчитать сколько в аккаунтах есть пользователей не на латинице (то есть на русском языке, вариант “на китайском” автоматически отбрасываем, вряд ли такие есть вообще).
all_rus_users = all_users[all_users['check_name']==0]
count_rus_users = all_rus_users.groupby('account_id', as_index = False).agg({'user_id':'count'}).rename(columns ={'user_id':'rus_count_users'})
Далее объединяем эти две получившиеся таблички по account_id.
users_merged = pd.merge(count_rus_users, count_eng_users, on = ['account_id'], how = 'outer').fillna(0)
В результате получим табличку users_merged с колонками: account_id, rus_count_users, eng_count_users
Посчитаем % :
users_merged['% иностранных пользователей'] = round(((users_merged['eng_count_users']/(users_merged['eng_count_users']+users_merged['rus_count_users']))*100),1)
🚀 Ну и зафиналим. Отберем те аккаунты, у которых у которых более 70% пользователей с именами на латинице:
df_eng_name_users_more70 = users_merged[users_merged['% иностранных пользователей']>=70]
А вот тут можно потренироваться с регулярками:
🔹www.regextester.com
🔹regex101.com
Если Вам нравится, что я привожу рабочие примеры, то ставьте лайки👍, огонечки 🔥 и прочее.
Очень много блогов, где есть ссылки на статьи, какие-то примеры с питоном и sql, но почти не встречала, чтобы аналитики показывали свой код, какие-то задачи с работы. Надеюсь, Вы это оцените ❤️
⁉️ Озадачили тут меня недавно запросом. Реально ли найти клиентов (account_id) у которых более 70% пользователей с именами на латинице.
- Конечно реально, - ответила я и принялась
^ - Соответствует началу строки.
[a-zA-Z] — любая буква на латинице в нижнем и верхнем регистре;
[0-9] — любая цифра от нуля до девяти
🔹 Как пример:
import re
s = "Yelena_Shon"
search = re.search(r'[a-zA-Z0-9]', s)
print(search)
Код выдаст <_sre.SRE_Match object; span=(0, 1), match='Y'>
🔹Еще вариант:
s = "Иван Петров"
search = re.search(r'[a-zA-Z0-9]', s)
print(search)
А этот код выдаст None
Но нам нужно как-то это применить в датафрейме, а не просто к строке, поэтому воспользуемся в дальнейшем apply.
🔥 Итак, я выкачала юзеров в датафрейм all_users со столбцами account_id, user_id, full_name.
Создадим столбец 'check_name', в котором будем записывать результат проверки
all_users['check_name']= all_users['full_name'].apply(lambda x: re.search(r'^[a-zA-Z0-9]',str(x))).fillna(0)
Затем отбираем там, где не ноль, чтобы потом посчитать юзеров написанных на латинице
all_eng_users = all_users[all_users['check_name']!=0]
Делаем группировку по аккаунтам c подсчетом количества пользователей (user_id) и создаем датафрейм count_eng_users. В нем будет две колонки: номера клиента-account_id и кол-во пользователей, написанных на латинице:
count_eng_users = all_eng_users.groupby('account_id', as_index = False).agg({'user_id':'count'}).rename(columns ={'user_id':'eng_count_users'})
Теперь то же самое сделаем, чтобы подсчитать сколько в аккаунтах есть пользователей не на латинице (то есть на русском языке, вариант “на китайском” автоматически отбрасываем, вряд ли такие есть вообще).
all_rus_users = all_users[all_users['check_name']==0]
count_rus_users = all_rus_users.groupby('account_id', as_index = False).agg({'user_id':'count'}).rename(columns ={'user_id':'rus_count_users'})
Далее объединяем эти две получившиеся таблички по account_id.
users_merged = pd.merge(count_rus_users, count_eng_users, on = ['account_id'], how = 'outer').fillna(0)
В результате получим табличку users_merged с колонками: account_id, rus_count_users, eng_count_users
Посчитаем % :
users_merged['% иностранных пользователей'] = round(((users_merged['eng_count_users']/(users_merged['eng_count_users']+users_merged['rus_count_users']))*100),1)
🚀 Ну и зафиналим. Отберем те аккаунты, у которых у которых более 70% пользователей с именами на латинице:
df_eng_name_users_more70 = users_merged[users_merged['% иностранных пользователей']>=70]
А вот тут можно потренироваться с регулярками:
🔹www.regextester.com
🔹regex101.com
Если Вам нравится, что я привожу рабочие примеры, то ставьте лайки👍, огонечки 🔥 и прочее.
Очень много блогов, где есть ссылки на статьи, какие-то примеры с питоном и sql, но почти не встречала, чтобы аналитики показывали свой код, какие-то задачи с работы. Надеюсь, Вы это оцените ❤️
👍54🔥27
И вот что он/она (наверно она, это же нейросеть) выдала:
Выбор карьеры в аналититике данных может быть привлекательным для многих профессионалов по следующим причинам:
Сначала я посмеялась с аналититики. А если серьезно, то действительно есть высокий спрос. Самый большой спрос на мидлов и выше, если честно. Но и джуну реально найти работу. Я же в свое время нашла.
Оплата действительно достойная. Буду надеяться что с каждым годом она будет достойнее и достойнее. 😂 Насчет профессионального роста — в точку. Есть много направлений в аналитике и есть куда расти и в чем совершенствоваться
В целом нейросетка права и я с ней согласна. Я бы еще добавила, что это еще и ИНТЕРЕСНО
Ну и если Вам нужен какой-то знак или ментальный пинок, чтобы начать/продолжить заниматься или подредактировать резюме и выходить на
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11👍8❤🔥1⚡1
Проклинаешь рекрутера за фидбэк, которого нет? Бог тебя услышал.
аналитик от бога — свежий канал про карьеру и проф развитие как для начинающих аналитиков, так и для тимлидов.
🅰️Владислав, ex-Teamlead из Альфа-банка, ярко и с юмором пишет заметки и статьи о том, как аналитику выйти на новый уровень в своей карьере.
Вот топ лучших постов канала:
♦️Как можно выделиться на фоне других кандидатов?
♦️Гайд по работе с документацией API
♦️Как аналитику проявить себя на новом проекте?
♦️Обзор API и протоколов
Сделай отклик в храм финтеха!
аналитик от бога — свежий канал про карьеру и проф развитие как для начинающих аналитиков, так и для тимлидов.
🅰️Владислав, ex-Teamlead из Альфа-банка, ярко и с юмором пишет заметки и статьи о том, как аналитику выйти на новый уровень в своей карьере.
Вот топ лучших постов канала:
♦️Как можно выделиться на фоне других кандидатов?
♦️Гайд по работе с документацией API
♦️Как аналитику проявить себя на новом проекте?
♦️Обзор API и протоколов
Сделай отклик в храм финтеха!
❤11👍1👎1🔥1
Что может пойти не так? ❓ Месяц назад выкладывала тут задание про поиск клиентов, у которых более 70% пользователей с именами на латинице. Сделала его на питоне. Питон крут и все такое.
Но есть проблемка.. выгрузки по 50 млн строк и питон хоть и тянет, но обрабатывает дооолго. Решила переписать на SQL. Но не просто SQL, а для Clickhouse. Ему такое – море по колено.🌊
Стала искать гуглить про регулярки для Clickhouse. И вот, что нашла: match(где ищем, шаблон)
Сначала concat соединяю фамилию и имя пользователя, а потом оборачиваю в match и вторым аргументом прописываем [A-Za-z] – ищем английские буквы как в большом, так и в малом регистре. А потом заворачиваем все это безобразие в sum, чтобы посчитать количество пользователей так как результат match выдает единички напротив каждого с английскими буквами (смотрим пример на картинке).
SUM(MATCH(CONCAT(IFNULL(uu.first_name,''),' ',IFNULL(uu.last_name,'')), '[A-Za-z]')) as has_latin_letters
Чтобы прописать сразу и rate пишем вот так:
select uu.ACCOUNT_ID,
count(uu.id) as all,
SUM(MATCH(CONCAT(IFNULL(uu.first_name,''),' ',IFNULL(uu.last_name,'')), '[A-Za-z]')) as has_latin_letters,
round((sum(match(CONCAT(IFNULL(uu.first_name,''),' ',IFNULL(uu.last_name,'')), '[A-Za-z]'))/
count(uu.id))*100,2) as rate
from user.user uu
where uu.ACCOUNT_ID in {tuple(df_accounts['account_id'])}
and uu.deleted = 0
and uu.type = 'user'
group by uu.ACCOUNT_ID
В результате скрипт летает как Карлсон в самом расцвете сил 🚀
Но есть проблемка.. выгрузки по 50 млн строк и питон хоть и тянет, но обрабатывает дооолго. Решила переписать на SQL. Но не просто SQL, а для Clickhouse. Ему такое – море по колено.🌊
Стала искать гуглить про регулярки для Clickhouse. И вот, что нашла: match(где ищем, шаблон)
Сначала concat соединяю фамилию и имя пользователя, а потом оборачиваю в match и вторым аргументом прописываем [A-Za-z] – ищем английские буквы как в большом, так и в малом регистре. А потом заворачиваем все это безобразие в sum, чтобы посчитать количество пользователей так как результат match выдает единички напротив каждого с английскими буквами (смотрим пример на картинке).
SUM(MATCH(CONCAT(IFNULL(uu.first_name,''),' ',IFNULL(uu.last_name,'')), '[A-Za-z]')) as has_latin_letters
Чтобы прописать сразу и rate пишем вот так:
select uu.ACCOUNT_ID,
count(uu.id) as all,
SUM(MATCH(CONCAT(IFNULL(uu.first_name,''),' ',IFNULL(uu.last_name,'')), '[A-Za-z]')) as has_latin_letters,
round((sum(match(CONCAT(IFNULL(uu.first_name,''),' ',IFNULL(uu.last_name,'')), '[A-Za-z]'))/
count(uu.id))*100,2) as rate
from user.user uu
where uu.ACCOUNT_ID in {tuple(df_accounts['account_id'])}
and uu.deleted = 0
and uu.type = 'user'
group by uu.ACCOUNT_ID
В результате скрипт летает как Карлсон в самом расцвете сил 🚀
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥41
И если родные, близкие и друзья пожимают плечами и говорят: "- Да, забей. Все равно не получится", то это демотивирует очень сильно. Я наслышана о разных историях, так как "варюсь" в этом уже давно и хотела предложить вам такую простую, но искреннюю идею.
А когда случается радость - и заветный оффер в кармане, то порадуемся за человечка от всего сердца ❤️. И пожелаем ему много сил, терпения и веры в себя. Ведь первый/второй и т.д. оффер - это бесконечный путь развития своих скиллов и себя как личности на бесконечной дороге профессионального роста.
Так что @m0t0rama, держись там! Мы мысленно с тобой, поздравляем с оффером и желаем удачи!
Еще с утра я не думала, что накатаю такой пост. Но что-то захотелось и по фиг, что сейчас уже поздно и наверно имело смысл подождать до завтра. Не всегда следует действовать логично, иногда нужно прислушиваться к сердцу.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤61👍10🔥8
А еще Александра заметила, что есть много вопросов по резюме, поэтому предложила свою помощь! Отправляйте ей свои резюме, она подскажет, где их нужно скорректировать и какими видят их эйчары.👌
Пишите на почту: susandra@inbox.ru с пометкой, что от канала Мир аналитика данных (так вас быстрее заметят)
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤5
🔥 Как тестировать SQL код при решении тестовых? Есть библиотека Pandasql. 🛠 Она позволяет выполнять SQL-запросы прямо в Юпитере, а вместо базы можно просто создавать DataFrame.
Например:
Выполнение SQL-запроса с помощью pandasql:
Таким образом, мы получаем результат, который содержит только user_id пользователей, которые ни разу не отменяли заказы.
Учитывая, что осень - пора активных собеседований, то кому-то это точно пригодится.✔️
P.S. Пост про то, какие онлайн сайты можно использовать для SQL у меня тут
Например:
from pandasql import sqldfПредположим, у нас есть таблица user_actions с информацией о действиях пользователей на нашем сервисе, включая id пользователя, id заказа и тип действия. Мы хотим отобрать всех пользователей, которые ни разу не отменяли заказы.
import pandas as pd
# Создание DataFrame user_actions
user_actions = pd.DataFrame({'user_id': [1, 1, 2, 3, 3],
'order_id': [101, 102, 103, 104, 105],
'action': ['create_order', 'cancel_order', 'create_order', 'create_order', 'cancel_order']})
Выполнение SQL-запроса с помощью pandasql:
query = """Мы используем подзапрос, чтобы получить все user_id пользователей, которые отменили заказы, и затем исключаем этих пользователей из основного запроса с помощью оператора NOT IN.
SELECT DISTINCT user_id
FROM user_actions
WHERE user_id NOT IN (
SELECT user_id
FROM user_actions
WHERE action = 'cancel_order'
)
"""
sqldf(query)
Таким образом, мы получаем результат, который содержит только user_id пользователей, которые ни разу не отменяли заказы.
Учитывая, что осень - пора активных собеседований, то кому-то это точно пригодится.
P.S. Пост про то, какие онлайн сайты можно использовать для SQL у меня тут
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥22👍2
📍 Пришло время упорядочить свои посты. Чтобы вам легче было в них ориентироваться и отыскать что-то нужное.
🐍🔤 🔤 🔤 🔤 🔤 🔤 ✨
- Живой кодинг на собеседовании. Примеры.
- Тестовое в Skyeng (ссылка на скрипт в комментариях)
- markdown и вставка картинок в Jupyter Notebook
- Метод format в Питоне
- Рабочий пример отчета для отдела продаж – формирование группы клиентов по разным условиям
- Особенности pivot_table на питоне
- Примеры сводной таблица pivot_table()
- Создание диапазона дат на питоне
- Рабочий скрипт по отвалу клиентов
- Отвал клиентов с доп.условиями
- Три топ клиента за год в каждой нише
- Кумулятивная функция сumsum()
- Примеры функции transform()
- Вопросы с собеседований по Python и Pandas
- Как определить к какой стране относится номер телефона? библиотека Phonenumbers
- Скрипт по когортному анализу (часть на SQL, часть на пандасе)
- Примеры np.where()
- Регулярные выражения на Питоне. модуль re
✨🔤 🔤 🔤 ✨ ✨
- Пример рабочего SQL скрипта в Jupyter Notebook
- Трафик, лиды, конверсия
- SQL Between
- HAVING в SQL
- Вопросы с собеседований по SQL
- Тестовое с решением
- Скрипт по когортному анализу (часть на SQL, часть на пандасе)
- Примеры использования CASE
- Group by на примере из курса Карпова и на рабочем примере.
- Регулярка для Clickhouse
- Библиотека Pandasql для написания SQL кода в Jupyter Notebook
✨🔤 🔤 🔤 🔤 🔤 ✨
- Как уменьшить вес Excel файла
- Excel vs Google таблицы
- Условное форматирование в Google таблицах.
- Выгрузка всех файлов с диска в Excel
✨☹️ ☹️ 😙 🤑 😓 😓 ✨
- Как я сменила профессию
- Какие бывают аналитики
- Мотивация
- Теория вероятности на минималках
- Как заходить в LinkedIn без VPN
- YandexGPT 2 рассказал почему стоит выбрать карьеру в аналитике данных
p.s. Вам знакомо то чувство чистоты, когда у вас на рабочем столе был бардак, а вы взяли и навели порядок? Книжки расставили по местам, бумаги рассортировали по папкам и протерли пыль с клавы. Вот сейчас что-то похожее ощущаю🍀
🐍
- Живой кодинг на собеседовании. Примеры.
- Тестовое в Skyeng (ссылка на скрипт в комментариях)
- markdown и вставка картинок в Jupyter Notebook
- Метод format в Питоне
- Рабочий пример отчета для отдела продаж – формирование группы клиентов по разным условиям
- Особенности pivot_table на питоне
- Примеры сводной таблица pivot_table()
- Создание диапазона дат на питоне
- Рабочий скрипт по отвалу клиентов
- Отвал клиентов с доп.условиями
- Три топ клиента за год в каждой нише
- Кумулятивная функция сumsum()
- Примеры функции transform()
- Вопросы с собеседований по Python и Pandas
- Как определить к какой стране относится номер телефона? библиотека Phonenumbers
- Скрипт по когортному анализу (часть на SQL, часть на пандасе)
- Примеры np.where()
- Регулярные выражения на Питоне. модуль re
✨
- Пример рабочего SQL скрипта в Jupyter Notebook
- Трафик, лиды, конверсия
- SQL Between
- HAVING в SQL
- Вопросы с собеседований по SQL
- Тестовое с решением
- Скрипт по когортному анализу (часть на SQL, часть на пандасе)
- Примеры использования CASE
- Group by на примере из курса Карпова и на рабочем примере.
- Регулярка для Clickhouse
- Библиотека Pandasql для написания SQL кода в Jupyter Notebook
✨
- Как уменьшить вес Excel файла
- Excel vs Google таблицы
- Условное форматирование в Google таблицах.
- Выгрузка всех файлов с диска в Excel
✨
- Как я сменила профессию
- Какие бывают аналитики
- Мотивация
- Теория вероятности на минималках
- Как заходить в LinkedIn без VPN
- YandexGPT 2 рассказал почему стоит выбрать карьеру в аналитике данных
p.s. Вам знакомо то чувство чистоты, когда у вас на рабочем столе был бардак, а вы взяли и навели порядок? Книжки расставили по местам, бумаги рассортировали по папкам и протерли пыль с клавы. Вот сейчас что-то похожее ощущаю
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥50❤6👍6💩2✍1❤🔥1
Мир аналитика данных pinned «📍 Пришло время упорядочить свои посты. Чтобы вам легче было в них ориентироваться и отыскать что-то нужное. 🐍 🔤 🔤 🔤 🔤 🔤 🔤 ✨ - Живой кодинг на собеседовании. Примеры. - Тестовое в Skyeng (ссылка на скрипт в комментариях) - markdown и вставка картинок в Jupyter…»
📍Горячие пирожки тестовые. Налетаем, разбираем, изучаем!
Есть табличка в Excel по продажам с указанием клиентов, проданных товаров, себестоимости, цены продажи. Нужно сделать следующие SQL запросы.
✅ Задача 1
Какая неделя стала лучшей по прибыли и указать саму сумму прибыли. Описания полей смотрите на картинке.
В таблице кроится небольшая хитрость. Есть колонка price_b2b_gross и колонка price_b2c_gross, а колонка количества купленных товаров в заказе только одна и не понятно к чему она относится – к b2b (юр.лицам) или к b2c (физ.лицам)
Считается, что вы или спросите или сами сделаете допущение, что наверно к b2c.
Загружаем файл в Юпитер (скачать ноутбук можно здесь , а файл с excel данными - вот тут берем), получаем датаффрейм и воспользовавшись библиотекой pandasql (о ней писала вот тут) пишете sql код. Не забываем, что эта библиотека реализует язык запросов СУБД SQLite. Поэтому есть конечно ряд ограничений, нельзя использовать операторы как в PostreSQL Например, DATE_PART('week', date_create). Нужно найти его аналогию и это strftime('%W',date_create), которая вытащит вам номер недели.
Сначала находим группировкой сумму прибыли за каждую неделю, не забываем указать в фильтре where status = 0 Так как в описании полей прописано, что Статус заказа (0 - Выдан, остальные - Отменен) А потом сортируем по сумме от большего к меньшему (order by 2 desc, 2, так как вторая колонка ) и берем ограничение в 1 строку limit 1. Ну и округлим до 2х знаков после запятой round() для красоты.
Есть нюанс, что если вот прям две недели совпали один в один, то вы потеряете инфу про вторую такую прибыльную неделю. Так как указан limit в одну строку. Вряд ли такое возможно, но есть вероятность. ⚡️
Поэтому покажем и 2ой способ скрипта. И чем больше вы продемонстрируете как вы можете сделать задачку и придумать способы, тем лучше. 👌
🌟 Сначала так же находим максимальную сумму за неделю. Потом находим, как и в первом варианте все недели и их суммы и в условии where прописываем, чтобы сумма из таблички с недельными суммами равнялась той максимальной сумме.
Мы можем уже обратиться тут к переменной amount, так как мы ее в подзапросе создали. И помним, что если подзапрос идем как табличка после FROM, то нужно указать ее название. Просто t1, допустим.
✅ Задача 2
Рассчитать маржу в рублях и % по всей компании за август. Вывести поля: Сайт, Приложение Строки: Маржа руб., Маржа %
Предоставить запрос в SQL и значения.
Во первых, маржа - это разница между себестоимостью товара и ценой, по которой продают товар. Почему тогда в первом задании назвали то же самое суммой прибыли? А вот и не важно, это тоже для того, чтобы вы подумали и поняли, что по сути это то же самое и формула будет такой же price_b2c_gross*quantity-cost_price*quantity
Продолжение в комментариях. 👉
Есть табличка в Excel по продажам с указанием клиентов, проданных товаров, себестоимости, цены продажи. Нужно сделать следующие SQL запросы.
✅ Задача 1
Какая неделя стала лучшей по прибыли и указать саму сумму прибыли. Описания полей смотрите на картинке.
В таблице кроится небольшая хитрость. Есть колонка price_b2b_gross и колонка price_b2c_gross, а колонка количества купленных товаров в заказе только одна и не понятно к чему она относится – к b2b (юр.лицам) или к b2c (физ.лицам)
Считается, что вы или спросите или сами сделаете допущение, что наверно к b2c.
Загружаем файл в Юпитер (скачать ноутбук можно здесь , а файл с excel данными - вот тут берем), получаем датаффрейм и воспользовавшись библиотекой pandasql (о ней писала вот тут) пишете sql код. Не забываем, что эта библиотека реализует язык запросов СУБД SQLite. Поэтому есть конечно ряд ограничений, нельзя использовать операторы как в PostreSQL Например, DATE_PART('week', date_create). Нужно найти его аналогию и это strftime('%W',date_create), которая вытащит вам номер недели.
Сначала находим группировкой сумму прибыли за каждую неделю, не забываем указать в фильтре where status = 0 Так как в описании полей прописано, что Статус заказа (0 - Выдан, остальные - Отменен) А потом сортируем по сумме от большего к меньшему (order by 2 desc, 2, так как вторая колонка ) и берем ограничение в 1 строку limit 1. Ну и округлим до 2х знаков после запятой round() для красоты.
Select strftime('%W',date_create) as 'лучшая неделя',
round(sum(price_b2c_gross*quantity-cost_price*quantity),2) as 'сумма прибыли'
From df
where status = 0
group by 1
order by 2 desc
limit 1Есть нюанс, что если вот прям две недели совпали один в один, то вы потеряете инфу про вторую такую прибыльную неделю. Так как указан limit в одну строку. Вряд ли такое возможно, но есть вероятность. ⚡️
Поэтому покажем и 2ой способ скрипта. И чем больше вы продемонстрируете как вы можете сделать задачку и придумать способы, тем лучше. 👌
🌟 Сначала так же находим максимальную сумму за неделю. Потом находим, как и в первом варианте все недели и их суммы и в условии where прописываем, чтобы сумма из таблички с недельными суммами равнялась той максимальной сумме.
Select weekofyear as 'лучшая неделя', round(amount,2) as 'сумма прибыли'
from
(
Select strftime('%W',date_create) AS weekofyear,
sum(price_b2c_gross*quantity-cost_price*quantity) as amount
from df
where status = 0
group by 1
) t1
-- фильтруем то, где сумма за неделю (t1.amount) будет равна максимальной сумме
where t1.amount = (Select max(amount) -- находим максимальную сумму за неделю
From
(Select strftime('%W',date_create) AS weekofyear,
sum(price_b2c_gross*quantity-cost_price*quantity) as amount
From df
where status = 0
group by 1)
t2)
Мы можем уже обратиться тут к переменной amount, так как мы ее в подзапросе создали. И помним, что если подзапрос идем как табличка после FROM, то нужно указать ее название. Просто t1, допустим.
✅ Задача 2
Рассчитать маржу в рублях и % по всей компании за август. Вывести поля: Сайт, Приложение Строки: Маржа руб., Маржа %
Предоставить запрос в SQL и значения.
Во первых, маржа - это разница между себестоимостью товара и ценой, по которой продают товар. Почему тогда в первом задании назвали то же самое суммой прибыли? А вот и не важно, это тоже для того, чтобы вы подумали и поняли, что по сути это то же самое и формула будет такой же price_b2c_gross*quantity-cost_price*quantity
Продолжение в комментариях. 👉
👍16❤6
✅ Когда где-то что-то дается бесплатно, то надо этим пользоваться. Тем более библиотека Pandas 🐼 - это прямо must have для аналитика! Это главная библиотека в Python для работы с данными. Вы это видите по моим скриптам.
☃10👍7💯1
Все-таки лучший способ для решения тестовых, для тренировки своих навыков в PostgreSQL – это установить базу к себе на компьютер и заливать туда csv файлы с нужными данными вместо создания таблиц. Да и оконки не потренируешь с pandasql, в которой синтаксис SQLite.
Я раньше думала, что это как-то сложно и потребуется много времени. Немного повозиться мне конечно пришлось, но зато теперь будет самая краткая инструкция!
Я выбрала 16 версию – самую новую. x64 - это 64-разрядная операционная система (какая у вас можно узнать в свойствах Мой компьютер). Там в характеристиках устройства указан тип вашей системы.
Запускаете инсталлятор – просто два раза щелкаете по файлу. В открывшемся окне выбираете Locale: «Russian, Russia» (русский язык в стране Россия) и далее выполняете то, что указано. Выбираете путь, где будет располагаться база. В конце установки снимите галочку в пункте Stack Builder. Там какие-то доп.утилиты предлагаются (не нужны короче, можно не заморачиваться)
На этом установка PostrgreSQL почти завершена!
В целом только с помощью pgAdmin можно писать запросы, но я привыкла работать через DBeawer. Поэтому переходим к следующему шагу.
У меня он уже установлен для работы. Идем в меню База данных. Там выбираем Новое соединение. Выбираем PostgreSQL. В настройках прописываем: Хост - localhost, база данных – postgres, Порт – тот номер Port из pgAdmin, пароль тоже вводим и жмем OK.
Теперь в списках баз DBeaver появился postgres с зеленой галочкой. Кликаете правой кнопкой мыши по postgres — Редактор SQL — Новый редактор SQL. Он Создадим схему. Пишем create schema test Теперь создадим таблицу. Сначала нужно обновить список объектов. Встаем на значок postgres внутри Базы данных и жмем F5. Появились наша схема test. А внутри название Таблицы. Правой клавишей мышки щелк и выбираем Импорт данных. В открывшимся окне, выбираем файл csv, который необходимо загрузить. Настраиваем параметры при необходимости. Здесь обращаю внимание на “Разделитель столбцов”, если в итоге вы получили некорректную таблицу, то необходимо проверить какой разделитель в исходном файле (иногда помогает сменить разделитель с запятой (,) на точку с запятой (;)). Нажимаем “Далее”, а потом “Продолжить”. Идет загрузка данных.
📌 И, ура, у нас табличка с нашими данными из файла! 🎯 Тип данных колонок можно менять прямо в свойствах.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16👍9❤3🤩1
📣 Я тоже буду интенсиве! Уже вижу что-то новое для себя. Да и тренировку на тестовых я люблю ❤️, это всегда на пользу.
☃5
Задание
Для выполнения этого задания требуется сгенерировать DataFrame с синтетическими данными. DataFrame должен состоять из 10000 строк и 5 колонок. Каждую из колонок мы предлагаем тебе создать и наполнить следующим образом:
🔹 1-я колонка – user_id – идентификатор пользователя. Длина user_id должна равняться 15-ти символам. Идентификатор состоит из случайной комбинации следующих символов: "1234567890abcdefghijk". Для каждой строки в DataFrame значение user_id формируются случайным образом.
🔹 2-я колонка – order_number – номер заказа. Столбец необходимо заполнить случайными значениями в диапазоне от 1 до 10.
🔹 3-я колонка – click2delivery – время, прошедшее с момента оформления заказа до вручения клиенту. Столбец необходимо заполнить случайными значениями из нормального распределения со средним 1440 и стандартным отклонением 200.
🔹 4-я колонка – order_items_sum – общая стоимость заказа. Значения для этого столбца необходимо взять из экспоненциального распределения с параметром λ = 1, смещённого на +1.
🔹 5-я колонка – retention – день жизни покупателя, в который он совершил заказ. Необходимо сгенерировать значения 1, 2, 3, 4, 5 с вероятностями 0.35, 0.25, 0.2, 0.15 и 0.05 соответственно.
В случае, если в колонке user_id встречаются дублирующиеся значения, оставь только первое из них.
Итак, импортируем библиотеки и задаем seed:
import pandas as pd
import numpy as np
import random
np.random.seed(42)
Это для того, чтобы скрипт выполнялся идентичным образом при каждом запуске. Мы предоставляем начальное значение (42 - популярный вариант).
Функция random.choice() возвращает один элемент из последовательности. Запихнем ее в созданную нами функцию generate_user_id(), а возвращать она будет соединенные join-ом выбранные по одному элементы из characters в количестве 15 штук.
def generate_user_id():
characters = "1234567890abcdefghijk"
return ''.join(random.choice(characters) for _ in range(15))
#Проверим как работает функция
generate_user_id()
'k4198854h3id213'
Теперь создадим функцию generate_df для генерации датафрейма.
И нашу функцию для user_id generate_user_id() запихнем в цикл for _ in range(n) чтобы нагенерировать 10 тыс строк.
Тут же создадим столбцы order_number, click2delivery, order_items_sum и retention.
def generate_df(n):
data = {
'user_id': [generate_user_id() for _ in range(n)],
'order_number': np.random.randint(1, 11, size=n),
'click2delivery': np.random.normal(1440, 200, size=n),
'order_items_sum': np.random.exponential(1, size=n) + 1,
'retention': np.random.choice([1, 2, 3, 4, 5], size=n, p=[0.35, 0.25, 0.2, 0.15, 0.05])
}
df = pd.DataFrame(data)
return df
df = pd.DataFrame()
А вы знали, что в питоне можно разряды в числах вот так показывать? n = 10_000 Я – нет. 😜
Пока длина df не будет 10 тыс будет выполняться соединение concat два датафрейма.
Условие n = 10_000 - len(df) при длине df 10 тыс строк будет равно 0 и while перестанет выполняться.
n = 10_000
while n:
new_df = generate_df(n)
df = pd.concat([df, new_df])
df = df.drop_duplicates(subset='user_id', keep='first')
n = 10_000 - len(df)
df.head()
Если хотите разбор следующих заданий в ближайшие дни ставим 🔥
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥77❤5
⭐️ Задание 2
Для всех строк исходного датасета, сгруппированных по номеру заказа, посчитать среднее значение времени доставки по группе. Результат необходимо добавить в новый столбец датафрейма.
У нас с прошлого задания сформировался датасет df со следующими полями:
user_id, order_number, click2delivery, order_items_sum, retention
Делаем обычную группировку:
orders = (
df
.groupby('order_number')['click2delivery']
.agg(mean_time='mean')
.reset_index()
)
Если мы пишем код в скобочках (), то можно вот так прописывать, перенося точку и метод на отдельные строки.
Ну и присоединим это среднее к основному df :
df = df.merge(orders, how='inner', on='order_number')
⭐️ Задание 3
Отдельной колонкой добавить значения последовательности, начинающейся с 0 и 1, где каждый следующий элемент является суммой двух предыдущих, умноженных на 0.5.
Задаем лист arr, а потом в цикле пока длина листа не составит 10 тыс, добавляем сумму двух предыдущих элементов, умноженных на 0.5:
arr = [0, 1]
while len(arr) < 10_000:
arr.append(sum(arr[-2:]) * 0.5)
df['seq'] = arr
Ну и еще было несколько заданий. 📎 Их найдете в файле юпитер ноутбука 👉 здесь
Please open Telegram to view this post
VIEW IN TELEGRAM
❤14✍3💯2⚡1
Нужно посчитать чистые рабочие часы сотрудников по дням без времени “на покурить” и обеды, когда они выходили из здания. Они могут ходить на улицу по несколько раз за день. И это тоже нужно учесть. Иногда сотрудники несколько раз прикладывают свой пропуск или пропускают по своему пропуску коллег, такое нужно исключать.
Тут нам поможет оконная функция LAG. Она используется для сравнения текущего значения колонки с предыдущим значением (в скобках смещение на 1 указала). Вот так мы узнаем время предыдущей записи:
lag (pass_date,1) over (partition by tab_id order by pass_date)
pass_date - это столбец, значение которого нужно сравнить с предыдущим значением.
partition by tab_id – берем партиции по номеру сотрудника и сортируем по дню order by pass_date
Когда мы из pass_date вычтем получившееся значение, то это будет разница между текущим временем (текущей строчкой) и временем предыдущего действия (вход либо выход) - time_diff
pass_date - lag (pass_date,1) over (partition by tab_id order by pass_date) as time_diff
Далее суммируем показатели текущего и предыдущего действия PASS_DIRECTION, тоже используя схему с lag
pass_direction +lag(pass_direction,1) over (partition by tab_id order by pass_date) as sum_enter
А теперь завернем все в подзапрос и прикрутим условие с фильтром. Мы суммируем время только когда выполняются два условия: sum_enter = 1 и pass_direction =0
sum(time_diff) filter (where (sum_enter = 1) and pass_direction =0)
В итоге:
select
working_date,
tab_id,
sum(time_diff) filter (where (sum_enter = 1) and pass_direction = 0)
from
(
select
date(pass_date) as working_date,
pass_date,
tab_id,
pass_direction,
-- разница между текущим временем и временем предыдущего действия
pass_date - lag (pass_date, 1) over (partition by tab_id order by pass_date) as time_diff,
-- суммируем показатели текущего и предыдущего действия (0+1 - то, что нужно), а если 1+1=2 - такое нам не надо
pass_direction + lag(pass_direction, 1) over (partition by tab_id order by pass_date) as sum_enter
from
test.newtable
order by
pass_date
) t1
group by 1, 2
💡 Тренируйте оконки, это прямо уже must have на собесах! Файл с данными забирайте для тренировки! 👌
Please open Telegram to view this post
VIEW IN TELEGRAM
❤28👍9🔥4❤🔥3☃2😁1