🔥 Ищем технического редактора (автора контента) к себе в команду
Друзья, мы расширяем команду и ищем человека, который будет помогать нам с контентом во всем его многообразии. Естественно, все на 100% связано с программированием и аналитикой. Вот примеры задач:
* создавать задачи и тесты для нас и наших корпоративных клиентов
* создавать посты в соцсети
* создавать обучающие материалы, пособия, шпаргалки и т.д.
Если вам это интересно - почитать про вакансию можно по ссылке (там же небольшое тестовое):
🔗 ссылка на вакансию
Работа очень интересная и масштабная - каждую единицу созданного вами контента будут видеть и использовать тысячи людей 🔥 Будем ждать вас в нашу команду 🙂
P.S. Идеального знания языков программирования не требуется.
- - - - -
А если эта вакансия может быть интересна вашим друзьям/родственникам/коллегам - обязательно перешлите им, пожалуйста.
Друзья, мы расширяем команду и ищем человека, который будет помогать нам с контентом во всем его многообразии. Естественно, все на 100% связано с программированием и аналитикой. Вот примеры задач:
* создавать задачи и тесты для нас и наших корпоративных клиентов
* создавать посты в соцсети
* создавать обучающие материалы, пособия, шпаргалки и т.д.
Если вам это интересно - почитать про вакансию можно по ссылке (там же небольшое тестовое):
🔗 ссылка на вакансию
Работа очень интересная и масштабная - каждую единицу созданного вами контента будут видеть и использовать тысячи людей 🔥 Будем ждать вас в нашу команду 🙂
P.S. Идеального знания языков программирования не требуется.
- - - - -
А если эта вакансия может быть интересна вашим друзьям/родственникам/коллегам - обязательно перешлите им, пожалуйста.
🔥6❤1👍1
🔥 Извлекаем абсолютно любые числа из строки с помощью регулярного выражения
Представьте, что вам дана строка, содержащая:
✓целые/дробные положительные/отрицательные числа
✓числа в стандартной записи и в научной записи (
✓абсолютно что угодно еще
🧠 А теперь решите задачу:
Нужно извлечь из этой строки только числа, притом во всех форматах.
Как это сделать? А давайте воспользуемся регулярными выражениями! Для примера возьмем строку:
s = '(3.22128 какой-то текст 0.353403 -0.0194664 еще какой-то текст 2e-15 some more text 15. 5 50e -100 )'
А теперь напишем такой код:
💡А очень просто: здесь с помощью регулярного выражения мы находим «кусочки», которые удовлетворяют шаблону. Давайте дадим небольшой комментарий:
С помощью сервиса regex101 вы можете удобно протестировать все возможные вариации строк с этой регуляркой. Работает железно и достойно ваших сохраненок 😁
- - - - -
🔗 Хотите научиться также просто решать боевые задачи? Приходите в симулятор «Аналитик данных»!
Представьте, что вам дана строка, содержащая:
✓целые/дробные положительные/отрицательные числа
✓числа в стандартной записи и в научной записи (
2e-10)✓абсолютно что угодно еще
🧠 А теперь решите задачу:
Нужно извлечь из этой строки только числа, притом во всех форматах.
Как это сделать? А давайте воспользуемся регулярными выражениями! Для примера возьмем строку:
s = '(3.22128 какой-то текст 0.353403 -0.0194664 еще какой-то текст 2e-15 some more text 15. 5 50e -100 )'
А теперь напишем такой код:
import re
[eval(el[0]) for el in re.findall('(-?\d+(e-\d+|.\d+)*)', s)]
🧐 На выходе мы получим список из чисел и ничего лишнего. Но как это получилось?!💡А очень просто: здесь с помощью регулярного выражения мы находим «кусочки», которые удовлетворяют шаблону. Давайте дадим небольшой комментарий:
-?
Перед числом может стоять знак «минус», а может и не стоять.\d+
Затем идет некая последовательность цифр (либо целая часть числа, либо основание в научной записи)(...|...)*
Затем может идти один из вариантов, разделенных |e-\d+
Научная запись: символ e, после которого идет - и какая-то последовательность цифр.\d+
Дробная часть: точка, а после нее цифры(...)
Финально оборачиваем все в скобки, чтобы извлечь полное число, а не его дробную/целую частьС помощью сервиса regex101 вы можете удобно протестировать все возможные вариации строк с этой регуляркой. Работает железно и достойно ваших сохраненок 😁
- - - - -
🔗 Хотите научиться также просто решать боевые задачи? Приходите в симулятор «Аналитик данных»!
🔥24👍2
🔥 Приходите к нам на онлайн мастер-класс по SQL
Завтра проводим бесплатный онлайн мастер-класс по SQL. Будем вас ждать! 😍
Ваш первый кейс в аналитике данных: исследуем продажи аптек
🎄 Дата: 21 декабря, среда
🎄 Время: 20:10 по Мск
🎄 Площадка: Youtube
🎄Бесплатно
Будем разбираться в SQL, обсуждать разные фишечки, писать ad-hoc запросы и анализировать деятельность реального бизнеса. Короче, будет интересно!
Ссылка на подключение и раздаточный материал придет сюда → ссылка, подписывайтесь 🙂
Завтра проводим бесплатный онлайн мастер-класс по SQL. Будем вас ждать! 😍
Ваш первый кейс в аналитике данных: исследуем продажи аптек
🎄 Дата: 21 декабря, среда
🎄 Время: 20:10 по Мск
🎄 Площадка: Youtube
🎄Бесплатно
Будем разбираться в SQL, обсуждать разные фишечки, писать ad-hoc запросы и анализировать деятельность реального бизнеса. Короче, будет интересно!
Ссылка на подключение и раздаточный материал придет сюда → ссылка, подписывайтесь 🙂
🔥12👍3
🔥 Уже скоро начнется наш онлайн мастер-класс по SQL
Напоминаем, что сегодня в 20:10 по Мск мы проводим мастер-класс по SQL. Что будем делать:
* Анализировать программу лояльности в аптечной сети
* Считать продуктовые метрики: LTV, ARPPU и другие
* Обсуждать интересные функции и приемы (unpivot, age и многое другое)
🔗 Ссылочка на вебинар, доступ к реальному кластеру и конспект-методичка доступны здесь 👉🏻 ссылка
Приходите, будет интересно! 🙂
Напоминаем, что сегодня в 20:10 по Мск мы проводим мастер-класс по SQL. Что будем делать:
* Анализировать программу лояльности в аптечной сети
* Считать продуктовые метрики: LTV, ARPPU и другие
* Обсуждать интересные функции и приемы (unpivot, age и многое другое)
🔗 Ссылочка на вебинар, доступ к реальному кластеру и конспект-методичка доступны здесь 👉🏻 ссылка
Приходите, будет интересно! 🙂
👍4🔥2❤1🤩1
👍3🔥2❤1
«Пишем цикл в одну строку» или list comprehension
При проверке домашних работ наших студентов мы часто натыкаемся на конструкцию такого вида:
✓
✓ А
Если Вы думаете, что это и так уже достаточное упрощение, Python снова позволяет нам сделать еще больше, и все в одну строку!
Что если нам нужны три условия?
Но давайте попробуем прочесть: для каждого
💡 Прекрасно, скажете Вы, мы можем написать 4 строки кода в одной, а есть ли в этом практический смысл?
Допустим, у нас есть список из 10000 элементов, нам нужно его отфильтровать и сформировать новый. Цикл
Теперь у вас есть не только эстетическая мотивация разобраться, но и практическая. А когда станет совсем легко, приглашаем ознакомиться с двойным list comprehension, мы рассказывали про него здесь!
При проверке домашних работ наших студентов мы часто натыкаемся на конструкцию такого вида:
lst = [1, 2, 3]Однако, Python замечателен тем, что позволяет писать элегантный, и почти такой же простой для чтения код, как обычный английский. Поэтому, можете даже не сомневаться, почти всегда есть возможность, сделать Ваш код короче. В нашем примере можно использовать list comprehesion.
result = []
for el in lst:
if el % 2 == 0:
result.append(el)
result = [i for i in lst if i % 2 == 0]
>> [2]🧠 Давайте разберемся как это работает.
Новый список = [выражение for элемент in iterable (if условие)]✓ В
выражении мы можем задать только элемент, вызвать какой-либо метод или обозначить выражение, возвращающее значение.✓
For элемент in iterable - это та же конструкция, которую мы используем в циклах for.✓ А
условие позволяет нам, одновременно с генерацией списка, добавлять фильтрацию.Если Вы думаете, что это и так уже достаточное упрощение, Python снова позволяет нам сделать еще больше, и все в одну строку!
Что если нам нужны три условия?
result = [i for i in lst if i % 2 == 0 and i > 1 or i == 3]
>> [2, 3]Или такая конструкция:
result = [i**2 for i in lst if i % 2 == 0 or i in [5, 9, 4, 7]]
>> [1, 4]Тут уже непонятно кто кого проверяет на прочность. То ли мы Python, то ли Python нас…
Но давайте попробуем прочесть: для каждого
i в lst, возвести i в квадрат и если i**2 четное или есть в переданном в условие списке - добавить в result. Уже стало понятнее!💡 Прекрасно, скажете Вы, мы можем написать 4 строки кода в одной, а есть ли в этом практический смысл?
Допустим, у нас есть список из 10000 элементов, нам нужно его отфильтровать и сформировать новый. Цикл
for отработает за 417 µs, а list comprehension - за 289 µs. Почти в два раза быстрее.Теперь у вас есть не только эстетическая мотивация разобраться, но и практическая. А когда станет совсем легко, приглашаем ознакомиться с двойным list comprehension, мы рассказывали про него здесь!
🔥12👍8❤1
🔥 «Большой О» уже стал вашим другом?
⏱ Обращали ли Вы когда-нибудь внимание на то, за сколько времени отрабатывает Ваш код?
Когда мы учимся, мы думаем «хорошо, что вообще отработал». Однако, в дальнейшем, это может сыграть злую шутку. Когда Вы приступите к большим проектам (а мы в этом не сомневаемся), придется чаще думать над ускорением работы, уменьшением объема памяти и многих других вещах. А
Вы, наверняка, уже возмутились, ведь время выполнения алгоритма зависит от устройства, на котором он запускается. Вы правы, но также и от количества входных данных.
Как же тогда это оценивать?
Ответ:
Главное!
Давайте сразу к примерам:
Еще один замечательный пример: линейный и бинарный поиск.
Не вдаваясь в подробности, сложность линейного поиска -
Сложность бинарного поиска -
Существенная экономия, и это при условии, что
Решить одну и ту же проблему зачастую можно многими способами. Задача умелого программиста — выбрать самый подходящий. Знание таинственной
Мы ближе познакомимся с
🏋️♀️ А пока разминка 👉 вы сможете написать алгоритм для чисел Фибоначчи за О(1)?
⏱ Обращали ли Вы когда-нибудь внимание на то, за сколько времени отрабатывает Ваш код?
Когда мы учимся, мы думаем «хорошо, что вообще отработал». Однако, в дальнейшем, это может сыграть злую шутку. Когда Вы приступите к большим проектам (а мы в этом не сомневаемся), придется чаще думать над ускорением работы, уменьшением объема памяти и многих других вещах. А
BIG O или О-нотация станет Вашим большим помощником.Вы, наверняка, уже возмутились, ведь время выполнения алгоритма зависит от устройства, на котором он запускается. Вы правы, но также и от количества входных данных.
Как же тогда это оценивать?
Ответ:
BIG O или О-нотация - Ваш неизменный помощник в вопросе сложности алгоритма.Главное!
BIG O показывает то, насколько сильно увеличивается время работы при увеличении входных данных. Это гораздо лучшая метрика для оценки, чем конкретное время работы!Давайте сразу к примерам:
O(n): при n=1 делается 1 шаг. При n=10 делается 10 шагов.
O(n²): при n=1 делается 1 шаг. При n=10 делается 100 шагов.
Заметьте, при n=1 эти двое будут работать одинаково!Еще один замечательный пример: линейный и бинарный поиск.
Не вдаваясь в подробности, сложность линейного поиска -
O(N), выглядит неплохо. Это, по сути, означает, что при увеличении входных данных в 2 раза, понадобится в 2 раза больше времени. Если данных будет в 100 раз больше, то и времени нам потребуется x100. Сложность бинарного поиска -
O(log N). Немного посчитав, обнаружим, что при увеличении входных данных, например, в 100 раз, затраченное время увеличится не в 100 раз (как в примере выше), а всего в 2,5 раза.Существенная экономия, и это при условии, что
BIG O оценивает худший вариант - то есть искомый элемент будет самым последним.Решить одну и ту же проблему зачастую можно многими способами. Задача умелого программиста — выбрать самый подходящий. Знание таинственной
O-нотации поможет заранее понимать как алгоритм будет проявлять себя в работе. Звучит как конкурентное преимущество, неправда ли?Мы ближе познакомимся с
BIG O в следующих постах, следите за обновлениями!🏋️♀️ А пока разминка 👉 вы сможете написать алгоритм для чисел Фибоначчи за О(1)?
🔥7👍5❤1🤩1
🔥 Ключевая метрика нашего бизнеса - rolling retention. Шпаргалка.
Встречайте rolling retention. Продолжаем нашу серию шпаргалок. Мы уже рассказывали вам про n-day retention вот 👉🏻 тут.
Давайте освежим ваши знания. Допустим, у нас 2 пользователя, один пользователь вернулся на 14-й день и на 45-й день, а второй пользователь - только на 44-й день. Каким будет n-day retention 14 дня? Верно, 50%. А rolling retention будет 100%. Как? А вот как!
❗️Rolling retention - это процент пользователей, которые вернулись к продукту в день N с момента знакомства или в любой из последующих дней.
🟢 Давайте сразу посмотрим пример.
У нас есть данные по 4 пользователям за 6 дней. Дни, когда пользователи взаимодействовали с продуктом - выделены галочкой, если поле пустое - пользователь был неактивен.
Посчитаем для них «классический»
Однако, на практике, с rolling retention бывают сложности. Например, у нас были пользователи, которых мы посчитали «отвалившимися», и при расчете rolling retention мы перестали их учитывать, а они вдруг взяли и вернулись! Теперь нам придется пересчитать rolling retention за все предыдущие дни. Но не пугайтесь сразу, обычно эта метрика считается динамически на дашбордах и т. п., так что эту работу за Вас сделает сама BI-система или интерактивный отчет 😊
Например, в последний раз пользователь был активен в 10-й день после первого контакта с продуктом. Затем мы рассчитали rolling retention на 25-й день, уже более не рассматривая этого пользователя. Однако он проявил активность на 30-й день. И чтобы учесть это - потребуется обновить rolling retention за все дни с 11-го по 30-е.
💡Где же это может быть удобно?
В то время как «классический» retention удобен для продуктов, которые используются ежедневно: соцсети, почта, игры. Rolling retention будет идеален для продуктов нерегулярного пользования, например, сайтов продажи авиабилетов. Он явно покажет, что пользователь может не быть активным каждый день, но все еще оставаться с нами. А еще мы в IT Resume активно используем эту метрику 😀
🎁 Хотите освоить аналитику данных с нуля на кейсах из реальной бизнес-практики? Присоединяйтесь к симулятору «Аналитик данных» со скидкой 50% до 31 декабря → ссылка на Симулятор
#продуктовые_метрики
Встречайте rolling retention. Продолжаем нашу серию шпаргалок. Мы уже рассказывали вам про n-day retention вот 👉🏻 тут.
Давайте освежим ваши знания. Допустим, у нас 2 пользователя, один пользователь вернулся на 14-й день и на 45-й день, а второй пользователь - только на 44-й день. Каким будет n-day retention 14 дня? Верно, 50%. А rolling retention будет 100%. Как? А вот как!
❗️Rolling retention - это процент пользователей, которые вернулись к продукту в день N с момента знакомства или в любой из последующих дней.
🟢 Давайте сразу посмотрим пример.
У нас есть данные по 4 пользователям за 6 дней. Дни, когда пользователи взаимодействовали с продуктом - выделены галочкой, если поле пустое - пользователь был неактивен.
Посчитаем для них «классический»
retention и rolling.| **День 1** | **День 2** | **День 3** | **День 4** | **День 5** | **День 6**Заметно, что rolling retention выше, чем “классический”, потому что он учитывает не только пользователей, которые были активны в один конкретный день, но и всех тех пользователей, которые вернулись позже.
-----------|------------|------------|------------|------------|------------|------------
User 1 | ✓ | ✓ | ✓ | | ✓ | ✓
User 2 | ✓ | ✓ | | ✓ | |
User 3 | | | | | |
User 4 | | ✓ | | | | ✓
Retention | 2/4 50% | 3/4 75% | 1/4 25% | 1/4 25% | 1/4 25% | 2/4 50%
Rolling | 3/4 75% | 3/4 75% | 3/4 75% | 3/4 75% | 2/4 50% | 2/4 50%
Однако, на практике, с rolling retention бывают сложности. Например, у нас были пользователи, которых мы посчитали «отвалившимися», и при расчете rolling retention мы перестали их учитывать, а они вдруг взяли и вернулись! Теперь нам придется пересчитать rolling retention за все предыдущие дни. Но не пугайтесь сразу, обычно эта метрика считается динамически на дашбордах и т. п., так что эту работу за Вас сделает сама BI-система или интерактивный отчет 😊
Например, в последний раз пользователь был активен в 10-й день после первого контакта с продуктом. Затем мы рассчитали rolling retention на 25-й день, уже более не рассматривая этого пользователя. Однако он проявил активность на 30-й день. И чтобы учесть это - потребуется обновить rolling retention за все дни с 11-го по 30-е.
💡Где же это может быть удобно?
В то время как «классический» retention удобен для продуктов, которые используются ежедневно: соцсети, почта, игры. Rolling retention будет идеален для продуктов нерегулярного пользования, например, сайтов продажи авиабилетов. Он явно покажет, что пользователь может не быть активным каждый день, но все еще оставаться с нами. А еще мы в IT Resume активно используем эту метрику 😀
🎁 Хотите освоить аналитику данных с нуля на кейсах из реальной бизнес-практики? Присоединяйтесь к симулятору «Аналитик данных» со скидкой 50% до 31 декабря → ссылка на Симулятор
#продуктовые_метрики
🔥7👍3🤩1
🔥 3 строки, которые написал бы middle в Pandas
1️⃣
Используете ли вы
2️⃣
Часто бывает так, что у нас есть переменная, к которой мы хотим обратиться в запросе. Как бы Вы это сделали? Наш топ встречаемого кода:
- Конкатенация
И напоследок, используя
- - - - -
🎁 Присоединяйтесь к симулятору «Аналитик данных» со скидкой 50% до 31 декабря → ссылка на Симулятор
#python #pandas
1️⃣
Используете ли вы
.query? Зачастую, когда необходимо отфильтровать датафрейм мы видим следующую конструкцию:df.loc[(df['Adults'] < 3) & (df['Children'] > 1)]
В выбранном здесь синтаксисе нет ничего плохого. Однако многие новые пользователи забывают, что в Pandas можно писать большие запросы, используя .query:df.query('Adults < 3 and Children > 1')
И чем сложнее будут становится ваши запросы, тем сильнее вы прочувствуете полезность .query.2️⃣
Часто бывает так, что у нас есть переменная, к которой мы хотим обратиться в запросе. Как бы Вы это сделали? Наш топ встречаемого кода:
- Конкатенация
df.query('Adults < ' + str(min_adults) + 'and Children > ' + str(min_children))
- f-строкиdf.query(f'Adults < {min_adults} and Children > {min_children}')
А знали ли вы, что ко внешним переменным можно просто обратиться через @?df.query('Adults < @min_adults and Children > @min_children')
3️⃣И напоследок, используя
.query нам бывает необходимо сформировать из результирующего датафрейма - новый. df_families = df.query('Adults < 3 and Children > 1')
Однако, когда мы решим изменить новый датафрейм, мы получим предупреждение SettingWithCopyWarning.df_families['First_name'] = df_families['Name'].str[-5:]
Дело в том, что Pandas позволяет нам выполнять, так называемую, цепную индексацию. Это повторный выбор строк/столбцов из результата предыдущего выбора строк/столбцов. Однако же, при подобных манипуляциях, предсказать что вернет нам Pandas - копию или представление - практически невозможно. Поэтому, чтобы обезопасить себя и быть уверенным в том, что модификации не появятся там, где их не ждали, лучше воспользоваться методом copy().df_families = df.query('Adults < 3 and Children > 1').copy()
df_families['First_name'] = df_families['Name'].str[-5:]
Он, по умолчанию, создаст глубокую копию и любые изменения в нашем новом датафрейме не отразятся в оригинальном.- - - - -
🎁 Присоединяйтесь к симулятору «Аналитик данных» со скидкой 50% до 31 декабря → ссылка на Симулятор
#python #pandas
👍19🔥7🤩1
🔥 Типичная ошибка в SQL: приоритет операторов
Часто в обучении встречаются задачи, где в
Живой пример: у нас есть таблица с информацией о разработчиках, которая содержит ФИО, язык разработки и уровень (junior/middle/senior).
Если нам нужно будет выбрать только middle и senior, мы запросто используем запрос:
Усложняемся: найдем всех middle и senior, пишущих на Python:
Дело в том, что операторы
Чтобы получить верный результат можно написать:
Легко заметить ошибку, когда мы явно видим, что не все строки удовлетворяют нашему условию, но когда строк миллион - найти такую ошибку будет уже невозможно.
Чувствуете уверенность в этой теме? Попробуйте решить задачу!
#sql
Часто в обучении встречаются задачи, где в
WHERE нужно передать несколько условий, и, порой, остальной запрос может быть верным, но будет возвращать некорректный результат из-за приоритета операторов.Живой пример: у нас есть таблица с информацией о разработчиках, которая содержит ФИО, язык разработки и уровень (junior/middle/senior).
Если нам нужно будет выбрать только middle и senior, мы запросто используем запрос:
SELECT ...(Надеемся вы знаете, что если вместо OR поставить AND- получим совсем не то, что нужно)
WHERE level = 'middle' OR level = 'senior'
Усложняемся: найдем всех middle и senior, пишущих на Python:
SELECT ...Все верно? Вот что мы получим:
WHERE level = 'middle' OR level = 'senior' AND language = 'python'
| name | language | level |В результирующей таблице появился php-разработчик, а мы его, как будто, и не просили.
|---------|----------|--------|
| Дмитрий | python | senior |
| Валерий | php | middle |
| Наталья | python | middle |
| Валерия | python | middle |
Дело в том, что операторы
OR и AND имеют разный приоритет, и у AND он - выше. Запрос сначала выбирает senior, использующих python, а далее срабатывает OR, который добавляет всех middle.Чтобы получить верный результат можно написать:
SELECT ...А лучше еще проще:
WHERE level = 'middle' AND language = 'python' OR level = 'senior' AND language = 'python'
SELECT ...Когда в одном запросе Вам приходится использовать и
WHERE (level = 'middle' OR level = 'senior') AND language = 'python'
OR, и AND - обращайте внимание на порядок выполнения, иначе можно запросто получить неверные данные. Особенно, если не знать, как выглядит исходная таблица и необходимый результат. А чтобы полностью обезопасить себя от ошибок с OR и AND - используйте скобки.Легко заметить ошибку, когда мы явно видим, что не все строки удовлетворяют нашему условию, но когда строк миллион - найти такую ошибку будет уже невозможно.
Чувствуете уверенность в этой теме? Попробуйте решить задачу!
#sql
🔥20👍8❤2
🔥 А вы знаете разницу между range between и rows between?
Давайте проведем с вами небольшой код ревью! Рассмотрим два небольших запроса и сравним их результаты.
1️⃣ Запрос первый:
Затрудняетесь с ответом? 🤔 Мы сейчас все расскажем!
Несомненно, вы знаете, что как ROWS, так и RANGE в SQL ограничивают строки внутри партиции оконных функций.
Однако,
В то время как
Показываем!
Пройдемся построчно по первому коду, использующему
🟢 Берём доход (для текущей строки) + cumulative_revenue (из предыдущей строки) = cumulative_revenue (для текущей строки). И так для каждого shop в таблице revenue.
В случае, если у нас появятся «дубликаты» (shop и period будут иметь одинаковые значения, а revenue будет отличаться)
🔵 Вы наверное уже догадались в чем подвох
И как же он с ними будет работать? Он обработает их вместе, сложив их revenue. То есть, доход (для текущей строки) + доход (для всех остальных строк с таким же shop и period) + cumulative_revenue (для предыдущей строки) = новый cumulative_revenue. Таким образом, мы получим единое значение совокупного дохода за период.
Это может показаться вам несущественной разницей, однако в реальном мире к концу периода не может быть двух разных значений совокупного дохода. А знание отличий
- - - - -
🎁 Присоединяйтесь к симулятору «Аналитик данных» со скидкой 50%, там мы подробно разбираем бизнес-кейсы с использованием SQL и Python → ссылка на Симулятор
#sql
Давайте проведем с вами небольшой код ревью! Рассмотрим два небольших запроса и сравним их результаты.
1️⃣ Запрос первый:
SELECT SUM(revenue) OVER(2️⃣ Запрос второй:
PARTITION BY shop
ORDER BY period ASC
ROWS UNBOUNDED PRECEDING
) AS cumulative_revenue
FROM revenue
SELECT SUM(revenue) OVER(Что скажете? Одинаково ли они отработают?
PARTITION BY shop
ORDER BY period ASC
RANGE UNBOUNDED PRECEDING
) AS cumulative_revenue
FROM revenue
Затрудняетесь с ответом? 🤔 Мы сейчас все расскажем!
Несомненно, вы знаете, что как ROWS, так и RANGE в SQL ограничивают строки внутри партиции оконных функций.
Однако,
ROWS делает это «в лоб». Он просто определяет фиксированное количество строк, которые предшествуют или следуют за текущей строкой, не принимая во внимание их значения. В то время как
RANGE ограничивает строки «логически». Это означает, что он учитывает не только количество предыдущих/следующих строк, но также берет во внимание значения в других строках по сравнению с текущей строкой.Показываем!
Пройдемся построчно по первому коду, использующему
ROWS.🟢 Берём доход (для текущей строки) + cumulative_revenue (из предыдущей строки) = cumulative_revenue (для текущей строки). И так для каждого shop в таблице revenue.
В случае, если у нас появятся «дубликаты» (shop и period будут иметь одинаковые значения, а revenue будет отличаться)
ROWS просто не обратит на это внимания, он продолжит брать доход текущей строки, прибавит cumulative_revenue предыдущей и выдаст новую cumulative_revenue.🔵 Вы наверное уже догадались в чем подвох
RANGE? Он, в свою очередь, будет использовать все предыдущие строки, текущую строку, а еще учтет строки содержащие одинаковые shop и period. И как же он с ними будет работать? Он обработает их вместе, сложив их revenue. То есть, доход (для текущей строки) + доход (для всех остальных строк с таким же shop и period) + cumulative_revenue (для предыдущей строки) = новый cumulative_revenue. Таким образом, мы получим единое значение совокупного дохода за период.
Это может показаться вам несущественной разницей, однако в реальном мире к концу периода не может быть двух разных значений совокупного дохода. А знание отличий
RANGE и ROWS и их уместное использование существенно повысит ваш профессиональный уровень!- - - - -
🎁 Присоединяйтесь к симулятору «Аналитик данных» со скидкой 50%, там мы подробно разбираем бизнес-кейсы с использованием SQL и Python → ссылка на Симулятор
#sql
🔥11👍4😱1
🔥 Ускоряем цикл в Python в 33000 раз
Мы уже рассказывали здесь о преимуществах list comprehension перед циклами, и зачастую list comprehension, действительно, наиболее читаемый и привычный способ работы со списками. Однако, python почти всегда позволяет решить одну задачу разными способами, тут-то самое время вспомнить о map!
Многие утверждают, что map более безопасный, быстрый, и вообще - это база. Проверим? Сгенерируем тренировочный список из 100000 отрицательных и положительных чисел.
- For Loop
- List Comprehension
- Map
Феноменально, при работе со встроенными функциями, map не просто в лидерах, он в 12000 раз быстрее! Может остальные методы нам и вовсе не нужны?
🔵 Давайте проверим map на невстроенных функциях, например, возведем элементы в квадрат.
- For Loop затратит
- List Comprehension -
- Map (используем lambda):
Это ли не чудо? Map быстрее в 33000 раз! Мы вам скажем, по секрету, что map вообще-то не очень жалует использование lambda (это несколько снижает скорость). А если бы мы преобразовали возвращаемый map объект в список, то затраченное время стало бы примерно таким же, как у list comprehension. Но! Map очень любит работать с готовыми функциями, в том числе с определенными пользователем. Поэтому напишем функцию
- List Comprehension:
- Map
Никого уже, наверное, не удивляет, map опять быстрее, в 20000 раз. Причем обратите внимание, ускорилась работа list comprehension -
🟣 Последнее, что мы еще не проверили, это добавление условий. Допустим, в результирующем списке должны быть только те числа, квадраты которых кратны 8.
- For Loop отработает за
- List Comprehension за
- Map, увы, не позволит сделать нам ничего подобного. Она может невероятно быстро применить функцию к каждому элементу массива, но удалить элемент - не может. Для таких случаев есть filter:
Ну что же, можно забывать про list comprehension и циклы, зачем они вообще нужны, когда есть map и filter, которые всегда в тысячи раз быстрее. Да?
Нет! Наверняка, знакомые с функцией map, уже хотят подловить нас на обмане. А именно, map никогда не возвращает список, только
Да, ни в одном из наших примеров, мы не формировали из возвращаемого
- - - - -
🎁 А вы уже успели присоединиться к симулятору «Аналитик данных» со скидкой 50%? → ссылка на Симулятор
#python
Мы уже рассказывали здесь о преимуществах list comprehension перед циклами, и зачастую list comprehension, действительно, наиболее читаемый и привычный способ работы со списками. Однако, python почти всегда позволяет решить одну задачу разными способами, тут-то самое время вспомнить о map!
Многие утверждают, что map более безопасный, быстрый, и вообще - это база. Проверим? Сгенерируем тренировочный список из 100000 отрицательных и положительных чисел.
lst = random.sample(range(-10000000, 10000000), 100000)
🟢 А теперь, воспользуемся тремя методами, и применим к списку встроенную функцию abs.- For Loop
lst_pos = []Время работы:
for i in lst:
lst_pos.append(abs(i))
7.98 ms.- List Comprehension
lst_pos = [abs(i) for i in lst]Время работы:
5.07 ms.- Map
lst_pos = map(abs, lst)Время работы:
419 ns.Феноменально, при работе со встроенными функциями, map не просто в лидерах, он в 12000 раз быстрее! Может остальные методы нам и вовсе не нужны?
🔵 Давайте проверим map на невстроенных функциях, например, возведем элементы в квадрат.
- For Loop затратит
23 ms.- List Comprehension -
20.9 ms.- Map (используем lambda):
map(lambda x: x**2, lst)
Время работы: 628 ns.Это ли не чудо? Map быстрее в 33000 раз! Мы вам скажем, по секрету, что map вообще-то не очень жалует использование lambda (это несколько снижает скорость). А если бы мы преобразовали возвращаемый map объект в список, то затраченное время стало бы примерно таким же, как у list comprehension. Но! Map очень любит работать с готовыми функциями, в том числе с определенными пользователем. Поэтому напишем функцию
pow2, которая принимает x и возводит его в квадрат - x * x.- List Comprehension:
[pow2(x) for x in lst]
Время: 8.6 ms.- Map
map(pow2, lst)
Время: 401 ns.Никого уже, наверное, не удивляет, map опять быстрее, в 20000 раз. Причем обратите внимание, ускорилась работа list comprehension -
8.6 ms против 20.9 ms, хотя делали мы одно и то же, просто разными способами. Берем на заметку!🟣 Последнее, что мы еще не проверили, это добавление условий. Допустим, в результирующем списке должны быть только те числа, квадраты которых кратны 8.
- For Loop отработает за
26.3 ms.- List Comprehension за
25.8 ms.- Map, увы, не позволит сделать нам ничего подобного. Она может невероятно быстро применить функцию к каждому элементу массива, но удалить элемент - не может. Для таких случаев есть filter:
filter(lambda x: x**2 % 8 == 0, lst)
И время: 542 ns.Ну что же, можно забывать про list comprehension и циклы, зачем они вообще нужны, когда есть map и filter, которые всегда в тысячи раз быстрее. Да?
Нет! Наверняка, знакомые с функцией map, уже хотят подловить нас на обмане. А именно, map никогда не возвращает список, только
map object, и это именно то, что отличает его от “конкурентов” и позволяет map оставаться впереди. Да, ни в одном из наших примеров, мы не формировали из возвращаемого
map object - список. Это существенно замедлило бы работу map, но даже если сделали бы - map все равно остался бы быстрее приблизительно в 1,5 - 2 раза (опять же, кроме случаев с использованием lambda). Но если вам так же, не нужны все вычисляемые значения сразу - выбирайте map, и тоже будете быстрее в 33000 раз!- - - - -
🎁 А вы уже успели присоединиться к симулятору «Аналитик данных» со скидкой 50%? → ссылка на Симулятор
#python
🔥12👍10🤩2
🔥 Стандартное отклонение в Python считается неправильно?!
Кто замечал, что при вычислении стандартного отклонения в Pandas и NumPy, вы получаете разные числа? Наверняка никто 🙂 А на днях, мы получили такой вопрос от студента.
Давайте проверим, действительно ли это так, если да - как это возможно, и как же добиться одинакового результата.
Создадим датафрейм для наших экспериментов.
- Pandas
Различие кроется в том, что Pandas и NumPy используют разные формлы для расчета стандартного отклонения. NumPy по умолчанию использует стандартное отклонение генеральной совокупности (в знаменателе
Время погрузиться в статистику! Когда мы вычисляем стандартное отклонение, необходимо понимать работаем мы с генеральной совокупностью или же с выборкой. Если с генеральной совокупностью - тогда делим на
Мы не можем сейчас подробно обсудить, почему мы должны использовать одну степень свободы, поскольку это довольно объемная тема. Если вам это интересно, напишите в комментариях и мы сделаем подобный пост.
В основном, в работе приходится иметь дело с выборками, поэтому в Pandas по умолчанию заложена формула для работы именно с ними (
А если вы хотите использовать определенную библиотеку, вы можете использовать параметр ddof - Delta Degrees of Freedom - для управления степенями свободы как в Pandas, так и в NumPy.
Давайте вернемся к старому примеру, где мы получили
Мы можем изменить степень свободы в NumPy, чтобы получить несмещенную оценку, используя параметр
Аналогично можно изменить вычисление стандартного отклонения Pandas, чтобы вовсе не использовать степени свободы:
- - - - - -
😏 Раз уж заговорили про библиотеки Python, Вы хорошо знаете Numpy? Пройдите тест и узнаете 😉
#python #pandas #numpy
Кто замечал, что при вычислении стандартного отклонения в Pandas и NumPy, вы получаете разные числа? Наверняка никто 🙂 А на днях, мы получили такой вопрос от студента.
Давайте проверим, действительно ли это так, если да - как это возможно, и как же добиться одинакового результата.
Создадим датафрейм для наших экспериментов.
df = pd.DataFrame({'height' : [161, 156, 172], 'weight': [67, 65, 89]})
Сосредоточимся только на столбце weight и посмотрим стандартное отклонение в Pandas и в NumPy.- Pandas
df.weight.std()- NumPy
>> 13.316656236958787
np.std(df.weight)Мы получаем 13,31 и 10,87. Это действительно совершенно разные цифры, так почему же?
>> 10.873004286866728
Различие кроется в том, что Pandas и NumPy используют разные формлы для расчета стандартного отклонения. NumPy по умолчанию использует стандартное отклонение генеральной совокупности (в знаменателе
N). А Pandas использует стандартное отклонение выборки (в знаменателе N - 1).Время погрузиться в статистику! Когда мы вычисляем стандартное отклонение, необходимо понимать работаем мы с генеральной совокупностью или же с выборкой. Если с генеральной совокупностью - тогда делим на
N (как в NumPy), а если с выборкой - на N - 1 (как в Pandas). Это называется одной степенью свободы, мы вычитаем 1, чтобы получить несмещенную оценку.Мы не можем сейчас подробно обсудить, почему мы должны использовать одну степень свободы, поскольку это довольно объемная тема. Если вам это интересно, напишите в комментариях и мы сделаем подобный пост.
В основном, в работе приходится иметь дело с выборками, поэтому в Pandas по умолчанию заложена формула для работы именно с ними (
N-1). Значит, стандартное отклонение Pandas является правильным?А если вы хотите использовать определенную библиотеку, вы можете использовать параметр ddof - Delta Degrees of Freedom - для управления степенями свободы как в Pandas, так и в NumPy.
Давайте вернемся к старому примеру, где мы получили
σ = 13,31 с помощью Pandas и σ = 10,87 с помощью NumPy.Мы можем изменить степень свободы в NumPy, чтобы получить несмещенную оценку, используя параметр
ddof:np.std(df.weight, ddof=1)И мы видим, что теперь результат совпадает со стандартным отклонением из Pandas.
>> 13.316656236958787
Аналогично можно изменить вычисление стандартного отклонения Pandas, чтобы вовсе не использовать степени свободы:
df.weight.std(ddof=0)Надеемся, что этот пост закрыл ваше любопытство и объяснил почему результаты стандартного отклонения изначально кажутся разными при использовании той или иной библиотеки.
>> 10.873004286866728
- - - - - -
😏 Раз уж заговорили про библиотеки Python, Вы хорошо знаете Numpy? Пройдите тест и узнаете 😉
#python #pandas #numpy
🔥34👍14🤩1
🔥 Задача с собеседования в e-commerce или про рекурсию в SQL
Мы столкнулись с тем, что на одном из технических интервью в e-commerce просили написать запрос, который выведет иерархию продукта. Хочется верить, что каждый из читающих сразу понял, что от него требуется. Но будем объективны, многие зависнут, мол, только с агрегациями разобрались, а это что еще за зверь.
💡 Давайте разбираться. Типичный пример иерархичной структуры - таблица сотрудников, где сами сотрудники также являются чьими-то менеджерами. То есть каждый сотрудник подотчетен другому, второй - третьему и так до тех пор, пока не останется тот, который никому не отчитывается. Это будет сотрудник верхнего уровня, и его
Теперь предположим, что нам нужно найти всех людей, которыми прямо или косвенно управляет сотрудник с
К счастью, нам не нужно ничего придумывать, в PostgreSQL есть специальная конструкция для таких запросов. Ее трудно объяснить без примера, поэтому давайте сразу смотреть на запрос:
Чтобы выполнить запрос рекурсивно, мы должны сообщить ему три вещи:
- Базовое условие - это первая часть запроса, в которой мы выбираем
- Ключевое слово UNION - сообщает PostgreSQL продолжать выполнять объединение для всех промежуточных строк, сгенерированных в результате рекурсии.
- Рекурсивная часть самого запроса - в нашем случае это условие, которое сопоставляет
🤯 Голова кипит? У нас тоже! На первый взгляд довольно сложно понять, но посмотрим пошагово как это работает. Запрос начинается с создания списка сотрудников с
С точки зрения синтаксиса, это все, что нужно для рекурсивного запроса. И да, мы признаем, что от этого голова кругом. Но есть целый пласт задач, которые можно решить только с помощью рекурсивных запросов и никак иначе. Поэтому владеть этим инструментом - крайне желательно, если вы решаете (или планируете) серьезные рабочие задачи.
👨🏻🎓 А чтобы глубже разобраться в SQL, приходите в наш Симулятор SQL
#sql #interview_problems
Мы столкнулись с тем, что на одном из технических интервью в e-commerce просили написать запрос, который выведет иерархию продукта. Хочется верить, что каждый из читающих сразу понял, что от него требуется. Но будем объективны, многие зависнут, мол, только с агрегациями разобрались, а это что еще за зверь.
💡 Давайте разбираться. Типичный пример иерархичной структуры - таблица сотрудников, где сами сотрудники также являются чьими-то менеджерами. То есть каждый сотрудник подотчетен другому, второй - третьему и так до тех пор, пока не останется тот, который никому не отчитывается. Это будет сотрудник верхнего уровня, и его
manager_id будет равен 0 или NULL.Теперь предположим, что нам нужно найти всех людей, которыми прямо или косвенно управляет сотрудник с
employee_id = 2. Как мы можем сделать это в одном запросе? Можно было бы использовать JOIN, но мы не знаем сколько раз его придется написать, поэтому JOIN нам тут не помощник. Но мы знаем, что поиск должен начаться с employee_id = 2 и с каждым разом искать подчиненных глубже и глубже, пока не зайдет в тупик. Звучит как рекурсия!К счастью, нам не нужно ничего придумывать, в PostgreSQL есть специальная конструкция для таких запросов. Ее трудно объяснить без примера, поэтому давайте сразу смотреть на запрос:
WITH RECURSIVE subordinates_of_2 AS (Часть
SELECT employee_id,
manager_id,
full_name
FROM employees WHERE employee_id = 2
UNION ALL
SELECT e.employee_id,
e.manager_id,
e.full_name
FROM employees e
JOIN subordinates_of_2 s2 ON e.manager_id = s2.employee_id
)
SELECT * FROM subordinates_of_2 WHERE employee_id <> 2;
WITH ... называется общим табличным выражением (CTE), за ней следует ключевое слово RECURSIVE, которое сообщает PostgreSQL, что следующее выражение должно быть выполнено рекурсивно. Что это значит?Чтобы выполнить запрос рекурсивно, мы должны сообщить ему три вещи:
- Базовое условие - это первая часть запроса, в которой мы выбираем
employee_id = 2.- Ключевое слово UNION - сообщает PostgreSQL продолжать выполнять объединение для всех промежуточных строк, сгенерированных в результате рекурсии.
- Рекурсивная часть самого запроса - в нашем случае это условие, которое сопоставляет
manager_id с employee_id, сгенерированными в предыдущих вызовах.🤯 Голова кипит? У нас тоже! На первый взгляд довольно сложно понять, но посмотрим пошагово как это работает. Запрос начинается с создания списка сотрудников с
employee_id = 2, затем продолжает объединять данные до тех пор, пока не останется ни одного сотрудника, с непустым manager_id. Поскольку конечный результат также включает менеджера верхнего уровня, мы отфильтровали его, используя WHERE employee_id <> 2.С точки зрения синтаксиса, это все, что нужно для рекурсивного запроса. И да, мы признаем, что от этого голова кругом. Но есть целый пласт задач, которые можно решить только с помощью рекурсивных запросов и никак иначе. Поэтому владеть этим инструментом - крайне желательно, если вы решаете (или планируете) серьезные рабочие задачи.
👨🏻🎓 А чтобы глубже разобраться в SQL, приходите в наш Симулятор SQL
#sql #interview_problems
👍18🔥7❤1
🔥 Full и return retention. Шпаргалка.
Сегодня мы завершаем нашу серию шпаргалок по метрикам retention на full и return retention.
🎧 Возьмем, например, музыкальный стриминговый сервис.
На начало месяца насчитывалось 100 000 пользователей. В течении этого месяца 80 000 из них ежедневно пользовались продуктом. Чтобы рассчитать
Итого:
🛍 В качестве примера возьмем сайт по продаже одежды.
В прошлом у него было 100 000 клиентов, в течение месяца, для которого мы рассчитываем
Таким образом,
Переоценить полезность данных метрик невозможно. Ведь если по
Главное - понимать, что показатели
🔴 Будьте аккуратны при выборе метрик, периодов расчета и интерпретации результатов! Приходите на симулятор Аналитика Данных, чтобы стать незаменимым в команде любого продукта.
#продуктовые_метрики
Сегодня мы завершаем нашу серию шпаргалок по метрикам retention на full и return retention.
Full retention - дает понимание того, насколько хорошо продукт или услуга удерживают пользователей с течением времени. Причем не просто удерживают в n-day, а каждый день.🎧 Возьмем, например, музыкальный стриминговый сервис.
На начало месяца насчитывалось 100 000 пользователей. В течении этого месяца 80 000 из них ежедневно пользовались продуктом. Чтобы рассчитать
full retention мы возьмем активных пользователей на конец периода (80 000 в нашем случае) и сравним с количеством пользователей на начало периода (100 000 в нашем случае).80 000/100 000 = 0,8
Итого:
full retention 80%.Return retention, в свою очередь, помогает понять насколько продукт способен возвращать пользователей. Он покажет сколько из них вернулись хотя бы 1 раз в течение заданного периода.🛍 В качестве примера возьмем сайт по продаже одежды.
В прошлом у него было 100 000 клиентов, в течение месяца, для которого мы рассчитываем
return retention, 5 000 вернулись и совершили покупку. Таким образом, взяв количество вернувшихся клиентов (5 000) и поделив на общее количество (100 000) получим return retention 5%.5 000/100 000=0,05В прошлой шпаргалке у нас была табличка с наглядной демонстрацией rolling retention, мы её обновили, добавив full и return (см. картинку под постом).
Таким образом,
full retention - это постоянно остающиеся с нами клиенты. Например, человек покупающий ежемесячную подписку на журнал на протяжении пяти лет.Return retention - возвращающиеся клиенты. Тот же пятилетний клиент, например, отменил подписку на месяц, а потом вернулся.Переоценить полезность данных метрик невозможно. Ведь если по
full retention мы увидим, что клиенты уходят, можно задуматься о внесении изменений в продукт и дополнительных методах удержания. Если return retention ниже, чем ожидается, есть смысл пересмотреть маркетинговые стратегии или программы лояльности.Главное - понимать, что показатели
retention, любого вида, будут разными у продуктов разной специфики. При сравнении full retention музыкальной стриминговой платформы с сайтом по продаже одежды, результаты будут разительно отличаться, но это не будет говорить о том, что один хуже удерживает клиентов, а другой лучше - они просто разные.🔴 Будьте аккуратны при выборе метрик, периодов расчета и интерпретации результатов! Приходите на симулятор Аналитика Данных, чтобы стать незаменимым в команде любого продукта.
#продуктовые_метрики
🔥8❤2👍2
🔥 Ускоряем работу в Pandas в 1000 раз
Мы никого не удивим, если скажем, что
И сегодня мы ускорим работу
Начнем, как всегда, с импортов и создадим датафрейм для наших экспериментов.
1️⃣ Наш первый кандидат ЦИКЛ
Запрашиваем новый датафрейм, итерируем по каждой строке и применяем
2️⃣ Проверим APPLY
Мы снова запросим датафрейм и применим к нему
3️⃣ И все-таки у нас есть третий кандидат - векторизация
Итак, мы напишем веторизованную версию того же кода с условиями. Она будет выглядеть так:
И возвращать серию булевых значений.
Теперь мы запрашиваем новый датафрейм, создаем
Вот так мы смогли ускорить наш код в 1000 раз и потому, очень рекомендуем вам использовать векторизацию там, где это возможно. Ведь по мере того, как вы начнете работать со все бóльшими и бóльшими наборами данных, этот трюк может стать незаменимым!
- - - - - - - -
🏋️♀️ Потренируйтесь решать рабочие задачи с помощью Pandas
#python #pandas
Мы никого не удивим, если скажем, что
Pandas - один из самых популярных пакетов python для работы с данными. И используя его каждый день, мы все равно находим новые фишечки, которые делают код быстрее, эффективнее и читабельнее. И сегодня мы ускорим работу
Pandas в 1000 раз, внеся всего несколько корректировок в код.Начнем, как всегда, с импортов и создадим датафрейм для наших экспериментов.
import pandas as pdТеперь мы хотим каждому человеку в соответствии с условиями - дать вознаграждение. Это будет наша функция
import numpy as np
def get_data(size = 10_000):
df = pd.DataFrame()
df['age'] = np.random.randint(0, 100, size)
df['time_in_bed'] = np.random.randint(0, 9, size)
df['pct_sleeping'] = np.random.rand(size)
df['favorite_food'] = np.random.choice(['pizza', 'taco', 'ice-cream'], size)
df['hate_food'] = np.random.choice(['broccoli', 'candy corn', 'eggs'], size)
return df
reward_calc:def reward_calc(row):Рассмотрим 3 способа применить подобную логику к набору данных, пойдем от самого медленного к самому быстрому. Что бы вам пришло в первую очередь при такой формулировке задачи?
if row['age'] >= 90:
return row['favorite_food']
if (row['time_in_bed'] > 5) & (row['pct_sleeping'] > 0.5):
return row['favorite_food']
return row['hate_food']
1️⃣ Наш первый кандидат ЦИКЛ
Запрашиваем новый датафрейм, итерируем по каждой строке и применяем
reward_calc().df = get_data()И время -
for index, row in df.iterrows():
df.loc[index, 'reward'] = reward_calc(row)
597 ms. Неплохо, можем ли мы лучше?2️⃣ Проверим APPLY
Мы снова запросим датафрейм и применим к нему
reward_calc() построчно. По сути, мы делаем то же самое, что и в цикле, но apply делает это эффективнее.df = get_data()Итого -
df['reward'] = df.apply(reward_calc, axis = 1)
107 ms. Это, конечно, не в миллион раз быстрее, чем цикл, а всего в 5,5. Но в больших датасетах, не как наш фиктивный на 10 000 строк, это будет крайне существенное ускорение.3️⃣ И все-таки у нас есть третий кандидат - векторизация
Итак, мы напишем веторизованную версию того же кода с условиями. Она будет выглядеть так:
((df['pct_sleeping'] > 0.5) &
(df['time_in_bed'] > 5)) |
(df['age'] > 90) И возвращать серию булевых значений.
Теперь мы запрашиваем новый датафрейм, создаем
reward, который будет равен hate_food, кроме случаев, где удовлетворены наши условия.df['reward'] = df['hate_food']И мы получаем
df.loc[((df['pct_sleeping'] > 0.5) &
(df['time_in_bed'] > 5)) |
(df['age'] > 90), 'reward'] = df['favorite_food']
4.41 ms, и бóльшая часть этого времени — это вызов get_data(). Без неё код отработает за 567 µs.Вот так мы смогли ускорить наш код в 1000 раз и потому, очень рекомендуем вам использовать векторизацию там, где это возможно. Ведь по мере того, как вы начнете работать со все бóльшими и бóльшими наборами данных, этот трюк может стать незаменимым!
- - - - - - - -
🏋️♀️ Потренируйтесь решать рабочие задачи с помощью Pandas
#python #pandas
👍16🔥6❤2
🔥 А как вы ответите на элементарный вопрос с собеседования?
Элементарный вопрос с собеседования. Объясните разницу между
🔹 Условие
🧑💻 Найдите среднемесячное количество продаж, используя WHERE и HAVING
#sql #interview_problems
Элементарный вопрос с собеседования. Объясните разницу между
WHERE и HAVING в SQL? Проверим совпадает ли ваш ответ с тем, чего ожидают рекрутеры?🔹 Условие
HAVING используется для фильтрации результатов запроса на основе агрегированных значений. Например, сгруппируем сотрудников по отделам, а потом выберем те, где сотрудников больше 10:SELECT department, COUNT(employee_id)🔹
FROM employees
GROUP BY department
HAVING COUNT(employee_id) > 10;
WHERE, в свою очередь, используется для фильтрации результатов на основе отдельных строк, до формирования групп. Например, сразу отфильтруем сотрудников с неподходящей заработной платой, и потом посчитаем количество подходящих сотрудников по отделам:SELECT department, COUNT(employee_id)Без сомнений, и
FROM employees
WHERE salary > 50000
GROUP BY department;
WHERE, и HAVING можно и нужно использовать вместе. Если до группировки можно отфильтровать неподходящие строки, то зачем их оставлять в HAVING?SELECT department, COUNT(employee_id)✅ Также стоит заметить, что
FROM employees
WHERE salary > 50000
GROUP BY department
HAVING COUNT(employee_id) > 10;
HAVING вполне может использоваться и без GROUP BY. Например, подобный запрос (без группировки) вернет нам одну строку - общее количество сотрудников, и только в том случае, если оно больше 10:SELECT COUNT(employee_id)❓ А теперь вопрос! Отработает ли данный код?
FROM employees
HAVING COUNT(employee_id) > 10;
DELETE FROM table- - - - - - -
HAVING COUNT(value) > 10;
🧑💻 Найдите среднемесячное количество продаж, используя WHERE и HAVING
#sql #interview_problems
👍9🔥6
🔥 Что такое процентиль и как его посчитать в Numpy
🧐 Давайте сегодня побудем исследователями. Представим, что у нас в руках оказались исторические данные с ежедневными измерениями температуры и осадков. Сразу хочется утереть нос метеорологам и показать, что мы не хуже них можем предсказать погоду.
Для этого нужно получить типичный диапазон температур и осадков.
Один из способов это сделать - использовать процентили.
Определение.
Следите за руками,
Процентиль может быть любым, хоть 89-й процентиль, хоть 14-й, в этом его удобство. Например, 5-й или 10-й процентиль часто используют для отслеживания выбросов. Ведь вполне логично, если только 5 процентов наблюдений меньше, то там могут оказаться аномально низкие значения, которые лучше не учитывать при анализе.
🔵 Итак, рассчитать процентиль нам позволяет
numpy.percentile(массив, для которого вычисляем процентиль; искомый процентиль или последовательность процентилей)
Например:
🔴 Таким образом, рассчитав так называемые «выбросы», например, 10 и 90 процентили, мы можем сформировать картину типичного диапазона температур и осадков для каждого дня года. И предположить эти показатели для будущих дней, взяв, например, 50 процентиль.
Глобально, процентили используются везде, где требуется некоторый анализ или сравнение. Они дают понимание распределения набора данных, помогают определить является ли оценка или наблюдение необычным или экстремальным.
Пройдите тест по библиотеке Numpy, чтобы понять как хорошо вы ее знаете 😏
#python #numpy
🧐 Давайте сегодня побудем исследователями. Представим, что у нас в руках оказались исторические данные с ежедневными измерениями температуры и осадков. Сразу хочется утереть нос метеорологам и показать, что мы не хуже них можем предсказать погоду.
Для этого нужно получить типичный диапазон температур и осадков.
Один из способов это сделать - использовать процентили.
Определение.
N-ый процентиль - это статистический показатель, определяющий значение, ниже которого будут N процентов наблюдений.Следите за руками,
25-й процентиль равен 7 - это значит, что 25% значений выборки будут меньше или равны 7. 100–й процентиль - это такое значение, что 100% выборки будут меньше или равны ему. Что это - догадываетесь? Это то же, что и максимальное значение. И если вам кажется, что 50-й процентиль очень напоминает медиану, то вы абсолютно правы!Процентиль может быть любым, хоть 89-й процентиль, хоть 14-й, в этом его удобство. Например, 5-й или 10-й процентиль часто используют для отслеживания выбросов. Ведь вполне логично, если только 5 процентов наблюдений меньше, то там могут оказаться аномально низкие значения, которые лучше не учитывать при анализе.
🔵 Итак, рассчитать процентиль нам позволяет
numpy. Синтаксис следующий:numpy.percentile(массив, для которого вычисляем процентиль; искомый процентиль или последовательность процентилей)
Например:
import numpy as npВывод: [3.25, 5.5, 7.75]
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
percentiles = np.percentile(data, [25, 50, 75])
print(percentiles)
🔴 Таким образом, рассчитав так называемые «выбросы», например, 10 и 90 процентили, мы можем сформировать картину типичного диапазона температур и осадков для каждого дня года. И предположить эти показатели для будущих дней, взяв, например, 50 процентиль.
Глобально, процентили используются везде, где требуется некоторый анализ или сравнение. Они дают понимание распределения набора данных, помогают определить является ли оценка или наблюдение необычным или экстремальным.
Пройдите тест по библиотеке Numpy, чтобы понять как хорошо вы ее знаете 😏
#python #numpy
👍8🔥6🤩1
🔥 Как операторы SQL могут подпортить жизнь
Все мы знакомы с предикатом сравнения
А сталкивались ли Вы когда-нибудь с
🔴 На днях один из наших студентов столкнулся проблемой: запросы
С одной стороны, они выглядят взаимозаменяемыми, но с другой стороны, вряд ли нужны два разных оператора, которые работают по одинаковой схеме.
А вы знаете в чем их отличие?
🟢 Давайте разбираться!
Допустим есть таблица компаний со столбцом company_id. Так получилось, что некоторым компаниям еще не присвоили id и пока их значения NULL. Она выглядит так:
⏩ А что же с is distinct from? Проверяем,
Аналогично,
⏩ А давайте попробуем получить результат, аналогичный
_ _ _ _ _ _ _
💥 Узнайте как COALESCE может помочь при решении рабочей задачи в нашей статье!
#sql
Все мы знакомы с предикатом сравнения
!= или <>. Это необходимый в работе, и довольно понятный оператор. А сталкивались ли Вы когда-нибудь с
IS DISTINCT FROM? Это еще один оператор, который также проверяет неравенство одного значения другому.🔴 На днях один из наших студентов столкнулся проблемой: запросы
IS DISTINCT FROM 1 и !=1 дали разные результаты.С одной стороны, они выглядят взаимозаменяемыми, но с другой стороны, вряд ли нужны два разных оператора, которые работают по одинаковой схеме.
А вы знаете в чем их отличие?
🟢 Давайте разбираться!
Допустим есть таблица компаний со столбцом company_id. Так получилось, что некоторым компаниям еще не присвоили id и пока их значения NULL. Она выглядит так:
| company_id |⏩ Написав запрос
|------------|
| 1 |
| 2 |
| 3 |
| 1 |
| NULL |
company_id != 1, получим:| company_id |Это именно то, чего мы и ожидали. Все компании, id которых не равны единице.
|------------|
| 2 |
| 3 |
⏩ А что же с is distinct from? Проверяем,
company_id IS DISTINCT FROM 1:| company_id |Теперь нули тоже оказались учтены. Все потому, что
|------------|
| 2 |
| 3 |
| NULL |
IS DISTINCT FROM рассматривает NULL как сопоставимое значение. Получается, что 1 IS DISTINCT FROM NULL вернет True, а NULL IS DISTINCT FROM NULL вернет False. Аналогично,
IS NOT DISTINCT FROM проверяет равенство значений, как и оператор =, но, в отличии от равенства, NULL IS NOT DISTINCT FROM NULL вернет True. ⏩ А давайте попробуем получить результат, аналогичный
IS NOT DISTINCT FROM, используя старый добрый COALESCE. Итак, COALESCE(company_id, -1) != 1:| company_id |✅ Такое маленькое, но очень существенное различие операторов может сильно подпортить вам жизнь, особенно в больших таблицах где присутствие или наоборот отсутствие
|------------|
| 2 |
| 3 |
| NULL |
NULL легко не заметить. Так что будьте предупреждены и вооружены!_ _ _ _ _ _ _
💥 Узнайте как COALESCE может помочь при решении рабочей задачи в нашей статье!
#sql
🔥13👍6🤩1