💥 А вы знакомы с оператором MERGE в PostgreSQL?
На одном из собеседований нашего студента спросили "что делает оператор MERGE?". И хотя это, прямо скажем, не первая по важности вещь для аналитика, все-таки может быть полезна.
🟣 Так что же такое MERGE?
Представьте, что у вас есть таблица с инвентарем товаров, которые продает ваша компания. Время от времени вы получаете наборы данных либо с новыми продуктами, которые необходимо внести, либо списки товаров в наличии, которые могут иметь или не иметь расхождения с инвентарем.
Обычно такое обновление можно выполнить в стороннем приложении. Проблема только в перетаскивании данных туда-сюда, которые вероятно придется сделать несколько раз (из базы в приложение, и обратно), а это много дополнительных издержек (в данном случае времени).
🖋 Но с недавнего времени в этом нет необходимости, благодаря
Для работы с
🔵 Как это работает?
Начнем с двух таблиц и одной строки данных.
Указанная в запросе логика будет выполнена, и значение столбца x увеличится с 1 до 2.
И, каждый раз, когда мы перезапускаем запрос с
🟡 Можем и удалить!
Мы можем не только обновлять (
Теперь вы точно знаете, что ответить на собеседовании, и что
#sql #interview_problems
На одном из собеседований нашего студента спросили "что делает оператор MERGE?". И хотя это, прямо скажем, не первая по важности вещь для аналитика, все-таки может быть полезна.
🟣 Так что же такое MERGE?
MERGE - оператор, который заменяет сразу несколько других. Представьте, что у вас есть таблица с инвентарем товаров, которые продает ваша компания. Время от времени вы получаете наборы данных либо с новыми продуктами, которые необходимо внести, либо списки товаров в наличии, которые могут иметь или не иметь расхождения с инвентарем.
Обычно такое обновление можно выполнить в стороннем приложении. Проблема только в перетаскивании данных туда-сюда, которые вероятно придется сделать несколько раз (из базы в приложение, и обратно), а это много дополнительных издержек (в данном случае времени).
🖋 Но с недавнего времени в этом нет необходимости, благодаря
MERGE все можно легко сделать прямо в базе. Для работы с
MERGE нужны две таблицы. Таблица с обновлениями и основное хранилище данных - целевая таблица. Содержимое таблицы с обновлениями сравнивается с целевой, и в целевой таблице происходят изменения.🔵 Как это работает?
Начнем с двух таблиц и одной строки данных.
create table a (id int, x int, status char(10));Теперь мы можем попробовать
create table b (id int, x int, status char(10));
insert into a (id, x, status) values (1, 1, 'From a');
select * from a;
select * from b;
id | x | status
---+---+------------
1 | 1 | From a
(1 row)
id | x | status
---+---+--------
(0 rows)
MERGE в запросе. Таблица a содержит одну строку, а в таблице b - строк вообще нет. И в запросе записи, не включенные в целевую таблицу, мы вставляем, а те, которые есть, обновляем:MERGE into b using a on a.id = b.idЗапрос сообщает - сопоставь две таблицы по
when matched then
update set x = b.x + 1
when not matched then
insert (id, x, status) values (a.id, a.x, a.status);
id. Если есть строки, которые совпадают, то столбец x в таблице b увеличь на единицу. Но если совпадений нет (совпадения не будет, так как таблица b пуста), то содержимое строки из таблицы a копируется в таблицу b. Если мы теперь посмотрим на обе таблицы, мы увидим, что они идентичны. select * from a;🟢 А что если запустить MERGE снова?
select * from b;
id | x | status
----+---+------------
1 | 1 | From a
(1 row)
id | x | status
----+---+------------
1 | 1 | From a
(1 row)
Указанная в запросе логика будет выполнена, и значение столбца x увеличится с 1 до 2.
select * from a;
select * from b;
id | x | status
---+---+------------
1 | 1 | From a
(1 row)
id | x | status
---+---+------------
1 | 2 | From a
(1 row)
И, каждый раз, когда мы перезапускаем запрос с
MERGE - x будет увеличиваться.🟡 Можем и удалить!
Мы можем не только обновлять (
UPDATE) значения, но и удалять их. Например, давайте изменим наш запрос так, чтобы не увеличивать значение, а удалять строку в целевой таблице, если найдутся соответствующие строки.merge into b using a on a.id = b.idПримечание: операция
when matched then delete
when not matched then
insert (id, x, status) values (a.id, a.x, a.status);
select * from b;
id | x | status
----+---+--------
(0 rows)
MERGE доступна только в PostgreSQL 9.5 и более поздних версиях.Теперь вы точно знаете, что ответить на собеседовании, и что
MERGE чрезвычайно полезный инструмент. И даже эти очень простые примеры дают представление о его использовании. Во многих ситуациях ранее приходилось бы использовать множество дополнительных конструкций для такого обновления, а теперь достаточно знать один MERGE.#sql #interview_problems
🔥18👍6
🔥 Продуктовая метрика LIFETIME
Периодически мы все принимаем волевые решения «с понедельника» освоить новый навык или что-то изменить, например, изучать новый язык или ходить в зал. Некоторые попробуют пару дней и бросят, другие могут остаться в этой затее на несколько месяцев, но в итоге потерять интерес, в то время как единицы продолжат практиковаться долгие годы.
И ситуация с любым продуктом точно такая же - большинство людей перестанут им пользоваться, как только пропадет интерес или потребность, в то время как некоторые будут пользоваться им годами.
Это как раз показатель востребованности продукта, заинтересованности юзеров и, более того, «гарантия» их финансовой активности. И этот показатель -
Важно: мы не рассматриваем, контактировал ли пользователь с продуктом каждый день, но рассматриваем общее количество дней (с первого до последнего контакта), проведенных с продуктом.
Как считать?
Обычно
Есть несколько способов расчета
🟢 Наиболее точный способ
Берем группу пользователей, ждем пока все они полностью «отвалятся», и считаем среднее количество времени, которое они провели с нами до ухода.
Например, у нас есть когорта из 100 пользователей, и мы знаем, сколько дней они провели в проекте прежде, чем покинули его:
| Число клиентов | Кол-во дней |
| 30 | 1 |
| 20 | 7 |
| 10 | 14 |
| 10 | 18 |
| 10 | 22 |
| 5 | 31 |
| 5 | 40 |
| 5 | 45 |
| 5 | 54 |
В этом случае их
❓ Но, чувствуете подвох? Расчет точного
Поэтому обычно мы, грубо говоря, оцениваем
🟡 Второй способ
Одним из способов оценить
🟣 Третий способ
Другой способ - вычисление интеграла от
Что нам дает lifetime?
Важно иметь в виду, что
Вот поэтому он очень полезен - он дает общую картину продукта всего одним числом.
При работе с
Разница между Lifetime и Lifetime Value
Мы не раз видели подобные вопросы от наших студентов. Тут важно понимать, что
💥 Более подробно обсуждаем продуктовые метрики: какие бывают, как считать, где применять, как анализировать на нашем Симуляторе «Аналитик данных»!
#analytics #продуктовые_метрики
Периодически мы все принимаем волевые решения «с понедельника» освоить новый навык или что-то изменить, например, изучать новый язык или ходить в зал. Некоторые попробуют пару дней и бросят, другие могут остаться в этой затее на несколько месяцев, но в итоге потерять интерес, в то время как единицы продолжат практиковаться долгие годы.
И ситуация с любым продуктом точно такая же - большинство людей перестанут им пользоваться, как только пропадет интерес или потребность, в то время как некоторые будут пользоваться им годами.
Это как раз показатель востребованности продукта, заинтересованности юзеров и, более того, «гарантия» их финансовой активности. И этот показатель -
Lifetime.Lifetime - это среднее время, в течение которого пользователь остается активным. Важно: мы не рассматриваем, контактировал ли пользователь с продуктом каждый день, но рассматриваем общее количество дней (с первого до последнего контакта), проведенных с продуктом.
Как считать?
Обычно
lifetime считается по когортам, и чем больше времени проходит с первого контакта, тем меньше пользователей из когорты продолжают использовать продукт. А самый большой отток обычно происходит в первые дни (см. картинку под постом). Есть несколько способов расчета
lifetime. 🟢 Наиболее точный способ
Берем группу пользователей, ждем пока все они полностью «отвалятся», и считаем среднее количество времени, которое они провели с нами до ухода.
Например, у нас есть когорта из 100 пользователей, и мы знаем, сколько дней они провели в проекте прежде, чем покинули его:
| Число клиентов | Кол-во дней |
| 30 | 1 |
| 20 | 7 |
| 10 | 14 |
| 10 | 18 |
| 10 | 22 |
| 5 | 31 |
| 5 | 40 |
| 5 | 45 |
| 5 | 54 |
В этом случае их
lifetime равен 15,6 дням.❓ Но, чувствуете подвох? Расчет точного
lifetime может занять достаточно много времени и это почти невозможно в реальной жизни, поскольку придется ждать, пока все пользователи окончательно прекратят использовать продукт.Поэтому обычно мы, грубо говоря, оцениваем
lifetime, а не считаем его. И при оценке мы опираемся в большей степени на retention.🟡 Второй способ
Одним из способов оценить
lifetime будет определение «точки невозврата», когда неактивные определенное количество дней (7, 14, 30) юзеры, считаются «отвалившимися».🟣 Третий способ
Другой способ - вычисление интеграла от
retention (поскольку lifetime - это площадь под кривой retention) или простое суммирование всех показателей retention. Для такого подсчета нам нужно знать retention за несколько дней, чем больше, тем лучше, так как это будет влиять на точность оценки.Что нам дает lifetime?
Важно иметь в виду, что
lifetime - это средняя цифра, т.е. она необязательно отражает точный день, когда пользователь покинет нас.Вот поэтому он очень полезен - он дает общую картину продукта всего одним числом.
При работе с
lifetime обращайте внимание на сегментацию. Можно делить пользователей по-разному: по стране, полу, устройству, а можно делить по проведенному времени с продуктом. То есть отдельно посмотреть на поведение юзеров с lifetime = неделя, две, месяц - вы сможете увидеть зависимости и, скорее всего, понять причины оттока.Разница между Lifetime и Lifetime Value
Мы не раз видели подобные вопросы от наших студентов. Тут важно понимать, что
LTV больше финансовая метрика (буквально наш доход от юзера за его lifetime). И хотя lifetime, в отличие от LTV, мы измеряем не в рублях, он все равно очень влияет на доход. Чем выше lifetime, тем дольше пользователь будет совершать платежи. Для сервисов с подпиской, это, пожалуй, особенно важные метрики.💥 Более подробно обсуждаем продуктовые метрики: какие бывают, как считать, где применять, как анализировать на нашем Симуляторе «Аналитик данных»!
#analytics #продуктовые_метрики
🔥10👍4❤2
🔥 Возможно, вы не знали этого о циклах for в Python
Недавно поступил вопрос от наших студентов, которые недавно освоили
💡 Загадка
При использовании цикла
🟡 На самом деле, когда мы используем
Но в питоне
✅ При каждой итерации цикла
То есть после выполнения
🖋 А теперь комментарий от наших преподавателей
Если вам действительно необходимо переназначить переменную цикла, используйте
👉 Записывайтесь на наш бесплатный курс по Python, где вы с нуля освоите новый язык программирования!
#python
Недавно поступил вопрос от наших студентов, которые недавно освоили
for-loop в Python и принялись экспериментировать.💡 Загадка
При использовании цикла
for невозможно изменить переменную цикла и повлиять на итерацию:for i in range(5):Как видно, переменная
print(i)
i = 10
#0
#1
#2
#3
…
i не меняется, хотя мы попытались ее переназначить внутри цикла.🟡 На самом деле, когда мы используем
for-loop в Python, никто, как правило, не имеет намерений изменить переменную цикла внутри него. Но можно догадаться, откуда растут ноги. 🙂 Возможно, так могли бы поступить те, кто уже знаком с другими языками программирования, например, С++ или Java.Но в питоне
for-loops не работают таким образом. Изменение переменной цикла не влияет на итерацию.✅ При каждой итерации цикла
for Python извлекает следующий элемент из указанного итерируемого объекта (iterable) - например, range(5). Затем значение этого элемента присваивается переменной цикла - например, i.То есть после выполнения
range(5) или любого другого range(n), объект, созданный range, становится абсолютно независящим от изменений на протяжении итераций. Будто мы написали цикл: for i in [0, 1, 2, 3, 4].🖋 А теперь комментарий от наших преподавателей
Если вам действительно необходимо переназначить переменную цикла, используйте
while, о котором частенько забывают, как только знакомятся с for-loop:i=0Или:
while i < 5:
print(i)
i = 10
#0
i=0Это довольно простая вещь, но о ней стоит помнить при разработке!
while i < 5:
print(i)
i += 2
#0
#2
#4
👉 Записывайтесь на наш бесплатный курс по Python, где вы с нуля освоите новый язык программирования!
#python
👍14🔥9
🔥 Тонкости функции head в Pandas
Сегодня мы поделимся любопытной деталью из мира аналитики данных и нашей практики. Если вы работаете с Pandas, то наверняка знакомы с методом
🟡 Но у
🖋 Такие моменты часто имеют значение, например, при анализе транзакций, чтобы получить список n продуктов с самыми высокими продажами. Или мы, анализируя активность на
🟢 И чтобы избежать этого, мы используем метод
‼️ В нашем бесплатном курсе по Python рассказываем, как работать с модулями и библиотеками Python: как устанавливать, импортировать и какие могут быть подводные камни ☺️
#python #pandas
Сегодня мы поделимся любопытной деталью из мира аналитики данных и нашей практики. Если вы работаете с Pandas, то наверняка знакомы с методом
head(). Он позволяет вывести первые n рядов вашего датафрейма.🟡 Но у
head() есть нюанс. Если данные содержат повторяющиеся значения, head() просто вернет первые строки и не станет учитывать их. Показываем пример:import pandas as pd
df = pd.DataFrame(
[['Игорь', 95],
['Яна', 100],
['Петр', 97],
['Иван', 95]],
columns = ['Имя', 'Оценка'])
df.sort_values('Оценка', ascending=False).head(3)
| | Имя | Оценка |
|---|-------|--------|
| 1 | Яна | 100 |
| 2 | Петр | 97 |
| 0 | Игорь | 95 |
В данном случае мы отсортировали датафрейм по столбцу 'Оценка' и просим вывести три первых позиции. Но если обратить внимание на значения оценок, то заметите, что у двух людей они равны. И если эти данные для вас важны, то использование head() может быть ошибкой.🖋 Такие моменты часто имеют значение, например, при анализе транзакций, чтобы получить список n продуктов с самыми высокими продажами. Или мы, анализируя активность на
itresume.ru при отборе страниц с наибольшим количеством посещений, не можем ограничиться head() - нам важны все значения (даже повторяющиеся).🟢 И чтобы избежать этого, мы используем метод
nlargest() вместо head(). Он позволяет извлекать верхние k строк отсортированного датафрейма, учитывая повторяющиеся значения. Давайте рассмотрим пример:df.nlargest(n=3,
columns='Оценка',
keep='all')
| | Имя | Оценка |
|---|-------|--------|
| 1 | Яна | 100 |
| 2 | Петр | 97 |
| 0 | Игорь | 95 |
| 3 | Иван | 95 |
Здесь мы указываем желаемое поведение для повторяющихся значений, используя параметр keep. В данном случае просим сохранить все строки с равными наивысшими оценками.‼️ В нашем бесплатном курсе по Python рассказываем, как работать с модулями и библиотеками Python: как устанавливать, импортировать и какие могут быть подводные камни ☺️
#python #pandas
🔥22👍13
🔥 CTE-запрос вместо case/when конструкций
В каждом посте мы делимся тем, что знаем и ежедневно используем. Но всего знать невозможно, и мы каждый день учимся и узнаем что-то новое. И рады делиться этим!
📎 Недавно мы наткнулись на очень любопытную конструкцию! Допустим, имеется таблица температур в различных локациях
🟣 Какая самая классическая задача для такой таблицы? Да, распределить значения на: жарко, тепло, холодно. Как чаще всего это реализуется? С помощью нескольких
🟢 Понятная классика! А мы нашли кое-что интереснее:
Не сказать, что эта запись короче, но посмотрите на сам подход!
👨🏻🎓 Те, кто не знаком с типами диапазонов, могут смутиться, увидев конструкцию
Возвращаясь к математике: круглые скобки означают, что граничные значения не входят в диапазон, а квадратные, что входят. Таким образом,
Отсутствующее значение
И последнее: необычный оператор
🤔 Может показаться, что это ненужное усложнение обыденной задачи, но спешим не согласиться! Данная задача - конечно проста, для облегчения понимания, но в условно больших таблицах бывает необходимо категоризировать несколько столбцов. Тогда для каждого из них придется писать
Вдобавок, для изменения или дополнения параметров категоризации, во втором варианте (в отличие от case/when) нам не придется затрагивать основной запрос - просто вносим правки в CTE и готово!
#sql
В каждом посте мы делимся тем, что знаем и ежедневно используем. Но всего знать невозможно, и мы каждый день учимся и узнаем что-то новое. И рады делиться этим!
📎 Недавно мы наткнулись на очень любопытную конструкцию! Допустим, имеется таблица температур в различных локациях
weather_stations:| station | temperature |P.S.: Данные, очевидно, фейковые 🙂
|---------|-------------|
| Moscow | 18.40 |
| Paris | 20.90 |
| London | 14.50 |
| Rome | 23.10 |
🟣 Какая самая классическая задача для такой таблицы? Да, распределить значения на: жарко, тепло, холодно. Как чаще всего это реализуется? С помощью нескольких
case/when конструкций: (карточка 1)🟢 Понятная классика! А мы нашли кое-что интереснее:
CTE-запрос, с использованием numrange (карточка 2)Не сказать, что эта запись короче, но посмотрите на сам подход!
👨🏻🎓 Те, кто не знаком с типами диапазонов, могут смутиться, увидев конструкцию
'( 0,10)' и тип данных numrange. Numrange - один из нескольких диапазонных типов, и он предназначен для диапазона числовых значений (бывают еще tsrange - для timestamp, daterange - для дат и другие).Возвращаясь к математике: круглые скобки означают, что граничные значения не входят в диапазон, а квадратные, что входят. Таким образом,
'(0,10]' означает "от 0, но не включая 0, и до 10 включительно".Отсутствующее значение
'[36,)' означает любое значение после, если это второе значение, или любое значение до, если первое - '(,0]'.И последнее: необычный оператор
<@ означает включен ли некоторый элемент в некоторый диапазон.🤔 Может показаться, что это ненужное усложнение обыденной задачи, но спешим не согласиться! Данная задача - конечно проста, для облегчения понимания, но в условно больших таблицах бывает необходимо категоризировать несколько столбцов. Тогда для каждого из них придется писать
case/when конструкцию. А формирование такого универсального CTE избавит от повторяющихся фрагментов и повысит читабельность.Вдобавок, для изменения или дополнения параметров категоризации, во втором варианте (в отличие от case/when) нам не придется затрагивать основной запрос - просто вносим правки в CTE и готово!
#sql
🔥16👍3🎉1
🔥 Создание поля объектов в Python с помощью setattr()
В работе с Python порой возникают ситуации, когда нужно динамически создавать поля объектов. Например, вы можете столкнуться с задачей занесения данных из словаря в атрибуты класса (мы столкнулись с такой задачей 🙂).
Код, который вы напишете для этой задачи, должен уметь обрабатывать различные словари со своим набором ключей и значениями. Неординарная задача. Но мы знаем, как это сделать!
🟢 Один из способов решения этой задачи - использовать функцию
Например, предположим, что у нас есть словарь my_dict:
📎 Такой подход кажется крайне удобным, потому что мы автоматизируем создание атрибутов и избегаем ручной обработки.
💡 Кроме того, функция
‼️ Чтобы освоить или улучшить свои навыки программирования на Python, присоединяйтесь к нашему бесплатному курсу!
#python
В работе с Python порой возникают ситуации, когда нужно динамически создавать поля объектов. Например, вы можете столкнуться с задачей занесения данных из словаря в атрибуты класса (мы столкнулись с такой задачей 🙂).
Код, который вы напишете для этой задачи, должен уметь обрабатывать различные словари со своим набором ключей и значениями. Неординарная задача. Но мы знаем, как это сделать!
🟢 Один из способов решения этой задачи - использовать функцию
setattr(). Эта функция позволяет динамически назначать поля объекта во время выполнения программы. Она принимает три аргумента: объект, имя атрибута и значение атрибута.Например, предположим, что у нас есть словарь my_dict:
my_dict = {
'name': 'Максим',
'age': 25,
'city': 'Москва'
}
Мы можем создать объект Person и использовать функцию setattr() для присвоения значений атрибутам:class Person:В результате мы получим объект Person с атрибутами name,
pass
p = Person()
for k, v in my_dict.items():
setattr(p, k, v)
age и city.📎 Такой подход кажется крайне удобным, потому что мы автоматизируем создание атрибутов и избегаем ручной обработки.
💡 Кроме того, функция
setattr() может пригодиться в других ситуациях, когда нужно динамически создавать поля объекта. Например, при работе с API или базами данных, когда набор полей может меняться в зависимости от запроса пользователя.‼️ Чтобы освоить или улучшить свои навыки программирования на Python, присоединяйтесь к нашему бесплатному курсу!
#python
🔥12👍7
🔥 Как «распаковать» массив в PostgreSQL?
В прошлых постах мы успели затронуть массивы в SQL и выяснили, что многие не сталкиваются с ним или вообще избегают, так как просто не умеют с ними работать.
На самом же деле все просто. В PostgreSQL есть множество функций, связанных с массивами. Начнем с
🟢 Функция
В более старых версиях PostgreSQL для этого приходилось использовать медленные и сложные методы, но с
Как использовать функцию unnest() в PostgreSQL?
Просто передайте ей массив, и она "распакует" его значения в строки таблицы.
Синтаксис:
А что насчет многомерных массивов?
Мы просто будем использовать синтаксис
🖋 А теперь попробуйте решить такую задачку:
> У вас есть таблица "books", где для каждой книги указаны ее ID и список авторов (хранится как массив). Используя функцию unnest(), найдите все книги, написанные авторами, чьи имена начинаются на букву "A".
Пишите ваши запросы в комментариях!
#sql
В прошлых постах мы успели затронуть массивы в SQL и выяснили, что многие не сталкиваются с ним или вообще избегают, так как просто не умеют с ними работать.
На самом же деле все просто. В PostgreSQL есть множество функций, связанных с массивами. Начнем с
unnest() - самой простой для понимания, на наш взгляд.🟢 Функция
unnest() позволяет "распаковать" массивы в строки. Это очень удобно, если нужно отобразить массивы в виде простой таблицы.В более старых версиях PostgreSQL для этого приходилось использовать медленные и сложные методы, но с
unnest() все стало гораздо проще.Как использовать функцию unnest() в PostgreSQL?
Просто передайте ей массив, и она "распакует" его значения в строки таблицы.
Синтаксис:
unnest(array)
🟡 Например, если есть массив с числами от 1 до 5, то можно применить функцию unnest() и получить каждое число в отдельной строке таблицы.SELECT unnest (ARRAY[1,2,3,4,5]);
| | unnest |Теперь давайте посмотрим, как сработает функция, если передать ей текст, а не цифры.
|---|--------|
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
SELECT unnest (ARRAY['яблоко', 'лимон', 'банан']);
| | unnest |Видим, что она работает одинаково как для строковых значений, так и для чисел.
|---|---------|
| 1 | яблоко |
| 2 | лимон |
| 3 | банан |
А что насчет многомерных массивов?
SELECT unnest (array[array[1, 2], array[2, 3], array[4,5]]);
| | unnest |А если с несколькими массивами разных типов данных? Запросто.
|---|--------|
| 1 | 1 |
| 2 | 2 |
| 3 | 2 |
| 4 | 3 |
| 5 | 4 |
| 6 | 5 |
Мы просто будем использовать синтаксис
unnest (array1, array2, array3…):SELECT * FROMА если они разных размеров?
unnest
(
array [1, 2, 3],
array ['HP', 'AMD', 'APPLE']
)
AS data(ID, Company);
| | id | company |
|---|----|---------|
| 1 | 1 | HP |
| 2 | 2 | AMD |
| 3 | 3 | APPLE |
SELECT * FROMЕсли массивы имеют разное число элементов, то функция автоматически дополнит их
unnest
(
array [1, 2, 3],
array ['HP', 'AMD', 'APPLE', 'DELL']
)
AS data(ID, Company);
| | id | company |
|---|--------|---------|
| 1 | 1 | HP |
| 2 | 2 | AMD |
| 3 | 3 | APPLE |
| 4 | [NULL] | DELL |
NULL - значениями до нужного размера.🖋 А теперь попробуйте решить такую задачку:
> У вас есть таблица "books", где для каждой книги указаны ее ID и список авторов (хранится как массив). Используя функцию unnest(), найдите все книги, написанные авторами, чьи имена начинаются на букву "A".
Пишите ваши запросы в комментариях!
#sql
👍12🔥8
🔥 Вакансия: Data Scientist (нейронные сети)
Сегодня мы с крутой новостью - ищем Data Scientist по направлению AI к себе в команду.
🔹 Направление: детекция объектов/текстов на изображениях (object detection, OCR)
🔹 Формат: удаленка, проект, частичная занятость/фултайм, с возможностью дальнейшего роста в международном стартапе
🔹 Опыт: от 1 года, наличие проектов object detection/OCR в портфолио
Присылайте свои резюме на почту a.alexanyan@itresume.ru и напишите в письме - почему именно вы подходите для этой вакансии 🙂
Будем рады видеть вас в команде! 🤩
Сегодня мы с крутой новостью - ищем Data Scientist по направлению AI к себе в команду.
🔹 Направление: детекция объектов/текстов на изображениях (object detection, OCR)
🔹 Формат: удаленка, проект, частичная занятость/фултайм, с возможностью дальнейшего роста в международном стартапе
🔹 Опыт: от 1 года, наличие проектов object detection/OCR в портфолио
Присылайте свои резюме на почту a.alexanyan@itresume.ru и напишите в письме - почему именно вы подходите для этой вакансии 🙂
Будем рады видеть вас в команде! 🤩
🔥8👍2
🔥 Степени свободы в статистике
Как-то мы делали пост о различиях расчета стандартного отклонения в NumPy и Pandas. И пообещали вам напомнить, а что же такое эти степени свободы, в которых вся соль. Сегодня об этом и поговорим.
Степени свободы в статистике - это количество независимых переменных, используемых при вычислении переменной.
Формула: Степени свободы = Количество независимых значений - Количество статистик
Пример. У нас есть 50 независимых значений, и мы хотим вычислить одну статистику - "среднее". Согласно формуле, степеней свободы будет 50 - 1 = 49.
🟢 Давайте представим, что вы проводите эксперимент, в котором измеряете рост 10 человек. Вы знаете среднее значение роста этих людей. Однако если бы вы измеряли рост еще большего количества людей, то среднее значение могло бы отличаться от результата, который вы получили изначально.
Почему? Во-первых, потому что мы берем лишь подмножество данных. А во-вторых, потому, что у нас есть ограничения в количестве данных, которые мы можем использовать. Эти ограничения и определяют степень свободы в нашем эксперименте.
Возвращаемся к стандартному отклонению. Как его считать?
1. Вычислите среднее значение набора данных.
2. Вычтите среднее значение из каждого значения в наборе данных.
3. Возведите в квадрат разности, полученные на шаге 2.
4. Сложите квадраты разностей, найденных на шаге 3.
5. Разделите сумму, полученную на шаге 4, на
6. Извлеките квадратный корень из результата шага 5, чтобы получить стандартное отклонение.
🟡 Концептуально мы можем понять это следующим образом: если бы мы имели доступ ко всей генеральной совокупности, мы могли бы точно вычислить истинное значение стандартного отклонения. Но если мы используем выборку, то у нас есть только ограниченный объем информации, который может привести к искажениям (и порой значительным).
Таким образом, мы должны скорректировать выборочную дисперсию, чтобы учесть этот факт. И именно поправка N
🟠 Вернемся к эксперименту с ростом людей.
Допустим, 10 человек - это генеральная совокупность, значения -
Используя NumPy, посчитаем стандартное отклонение генеральной совокупности: 13.14. Возьмем условную «выборку» - пять последних элементов, и посчитаем теперь для них.
✅ Итог: используя степени свободы, вы получите несмещенную оценку, и это обеспечит вам более точные результаты. Поэтому не забывайте, что в NumPy по умолчанию
🔵 В нашем Симуляторе «Аналитик данных» подробно разбираем библиотеки Python для анализа данных и показываем, как использовать их в рабочих задачах!
#analytics #pandas #numpy
Как-то мы делали пост о различиях расчета стандартного отклонения в NumPy и Pandas. И пообещали вам напомнить, а что же такое эти степени свободы, в которых вся соль. Сегодня об этом и поговорим.
Степени свободы в статистике - это количество независимых переменных, используемых при вычислении переменной.
Формула: Степени свободы = Количество независимых значений - Количество статистик
Пример. У нас есть 50 независимых значений, и мы хотим вычислить одну статистику - "среднее". Согласно формуле, степеней свободы будет 50 - 1 = 49.
🟢 Давайте представим, что вы проводите эксперимент, в котором измеряете рост 10 человек. Вы знаете среднее значение роста этих людей. Однако если бы вы измеряли рост еще большего количества людей, то среднее значение могло бы отличаться от результата, который вы получили изначально.
Почему? Во-первых, потому что мы берем лишь подмножество данных. А во-вторых, потому, что у нас есть ограничения в количестве данных, которые мы можем использовать. Эти ограничения и определяют степень свободы в нашем эксперименте.
Возвращаемся к стандартному отклонению. Как его считать?
1. Вычислите среднее значение набора данных.
2. Вычтите среднее значение из каждого значения в наборе данных.
3. Возведите в квадрат разности, полученные на шаге 2.
4. Сложите квадраты разностей, найденных на шаге 3.
5. Разделите сумму, полученную на шаге 4, на
N (если берем генеральную совокупность) , либо на (N - 1) (если берем выборку). На этом этапе мы получили дисперсию.6. Извлеките квадратный корень из результата шага 5, чтобы получить стандартное отклонение.
🟡 Концептуально мы можем понять это следующим образом: если бы мы имели доступ ко всей генеральной совокупности, мы могли бы точно вычислить истинное значение стандартного отклонения. Но если мы используем выборку, то у нас есть только ограниченный объем информации, который может привести к искажениям (и порой значительным).
Таким образом, мы должны скорректировать выборочную дисперсию, чтобы учесть этот факт. И именно поправка N
-1 в знаменателе, позволяет учитывать этот фактор.🟠 Вернемся к эксперименту с ростом людей.
Допустим, 10 человек - это генеральная совокупность, значения -
[150, 193, 173, 184, 168, 201, 178, 175, 180, 182].Используя NumPy, посчитаем стандартное отклонение генеральной совокупности: 13.14. Возьмем условную «выборку» - пять последних элементов, и посчитаем теперь для них.
import numpy as npВспомним, что NumPy считает стандартное отклонение для генеральной совокупности (в знаменателе
a = [201, 178, 175, 180, 182]
np.std(a)
# 9.195
N - без степеней свободы), а мы уже работаем с выборкой, и нам нужно добавить одну степень свободы (N-1). Посмотрим, приблизимся ли мы к изначальному результату.import numpy as npДействительно, стало поточнее. Конечно, 10 элементов с трудом можно назвать генеральной совокупностью, а половину - выборкой. Но убедиться, что это работает, можно!
a = [201, 178, 175, 180, 182]
np.std(a, ddof=1)
# 10.28
✅ Итог: используя степени свободы, вы получите несмещенную оценку, и это обеспечит вам более точные результаты. Поэтому не забывайте, что в NumPy по умолчанию
ddof=0, а в Pandas ddof=1.🔵 В нашем Симуляторе «Аналитик данных» подробно разбираем библиотеки Python для анализа данных и показываем, как использовать их в рабочих задачах!
#analytics #pandas #numpy
🔥9👍5❤2
🔥 Бесплатный live-курс по SQL для начинающих 🔥
Приветствую!
На связи Андрон, CEO Simulative & IT Resume.
Хочу пригласить вас на свой бесплатный live-курс по SQL для начинающих: "Сегментация базы пользователей", который пройдёт с 16 по 17 мая в 19:00 по мск. 💥
Этот live-курс подойдет Вам, если:
🔹 У вас совсем нет опыта в SQL;
🔹 Вы немного владеете базовым SQL, но нет системности;
🔹 Вы никогда не применяли SQL для решения бизнес-задач.
На live-курсе помимо лекций будут 2 блока домашних заданий, доступ к боевому кластеру и реальный бизнес-кейс, который вам предстоит решить самостоятельно.
КУРС АБСОЛЮТНО БЕСПЛАТНЫЙ! 😉
🔗 Чтобы не пропустить трансляцию и получить конспект, переходите по ссылке 👉 https://mnlp.cc/mini?domain=simulative&id=7.
До встречи! 🙂
Приветствую!
На связи Андрон, CEO Simulative & IT Resume.
Хочу пригласить вас на свой бесплатный live-курс по SQL для начинающих: "Сегментация базы пользователей", который пройдёт с 16 по 17 мая в 19:00 по мск. 💥
Этот live-курс подойдет Вам, если:
🔹 У вас совсем нет опыта в SQL;
🔹 Вы немного владеете базовым SQL, но нет системности;
🔹 Вы никогда не применяли SQL для решения бизнес-задач.
На live-курсе помимо лекций будут 2 блока домашних заданий, доступ к боевому кластеру и реальный бизнес-кейс, который вам предстоит решить самостоятельно.
КУРС АБСОЛЮТНО БЕСПЛАТНЫЙ! 😉
🔗 Чтобы не пропустить трансляцию и получить конспект, переходите по ссылке 👉 https://mnlp.cc/mini?domain=simulative&id=7.
До встречи! 🙂
🔥8👍3🤩2
💥 Напоминание о бесплатном live-курсе по SQL 💥
Приветствуем!
Возможно, вы пропустили наш прошлый пост, поэтому дублируем информацию еще раз 🙃
Приглашаем вас на бесплатный live-курс по SQL для начинающих: "Сегментация базы пользователей", который пройдёт с 16 по 17 мая в 19:00 по мск. 🔥
❓Что вас ждет на live-курсе:
🔸 2 живых обучающих лекции с разбором практических заданий;
🔸 2 блока домашних задания (15 заданий);
🔸 Самостоятельное решение бизнес-кейса с обратной связью от преподавателя;
🔸 Доступ к боевому кластеру;
🔸 Работа с профессиональными инструментами и программами.
🔗 Чтобы не пропустить трансляцию и получить конспект, переходите по ссылке 👉 https://mnlp.cc/mini?domain=simulative&id=7.
До встречи на live-курсе! 😉
Приветствуем!
Возможно, вы пропустили наш прошлый пост, поэтому дублируем информацию еще раз 🙃
Приглашаем вас на бесплатный live-курс по SQL для начинающих: "Сегментация базы пользователей", который пройдёт с 16 по 17 мая в 19:00 по мск. 🔥
❓Что вас ждет на live-курсе:
🔸 2 живых обучающих лекции с разбором практических заданий;
🔸 2 блока домашних задания (15 заданий);
🔸 Самостоятельное решение бизнес-кейса с обратной связью от преподавателя;
🔸 Доступ к боевому кластеру;
🔸 Работа с профессиональными инструментами и программами.
🔗 Чтобы не пропустить трансляцию и получить конспект, переходите по ссылке 👉 https://mnlp.cc/mini?domain=simulative&id=7.
До встречи на live-курсе! 😉
🔥9👍2
⁉️ А есть ли разница между Concat / Сoncat_ws / ||
Как часто вас учат, что можно заменить функцию
✏️ В PostgreSQL оператор
А что с NULL значениями?
Вот и ловушка! При использовании оператора
✅ Оператор
✅ А функции
❗️ Так что будьте осторожны и присоединяйтесь к Симулятору «Аналитик данных», чтобы оценить свои навыки на рабочих кейсах!
#sql
Как часто вас учат, что можно заменить функцию
concat оператором ||? А что, если мы скажем, что это не совсем так? Мы вместе с нашими студентами курса разбирались в этом во время решения домашних задач.✏️ В PostgreSQL оператор
|| - это бинарный оператор, который используется для конкатенации двух строковых значений. Он просто соединяет две строки вместе, не добавляя никаких разделителей или других символов между ними.SELECT 'IT' || 'Resume';В то время как функции
-- ITResume
concat() и concat_ws() также используются для конкатенации, но предоставляют некоторые дополнительные возможности. Например, функция concat() позволяет объединять любое количество строковых аргументов, а concat_ws() еще и принимает первым аргументом разделитель. SELECT concat('IT', ' ', 'Resume');
-- IT Resume
SELECT concat_ws('-', '2023', '05', '15');
-- 2023-05-15
И на этом можно было бы остановиться, ведь уже понятно их различие. Но мы были бы не мы, если бы на этом закончили.А что с NULL значениями?
Вот и ловушка! При использовании оператора
|| в PostgreSQL, если один из аргументов NULL, результат будет также NULL. Например:SELECT 'SQL' || NULL;А вот функции, вполне справятся с
-- NULL
NULL значениями:SELECT concat(NULL, NULL);Почему так?
-- ''
SELECT concat_ws(' ', 'IT', NULL, 'Resume');
-- IT Resume
✅ Оператор
|| работает по стандарту SQL, когда любое выражение, в котором участвует NULL должно равняться NULL. Потому что NULL это неизвестность. Как 42 * NULL даст NULL. ✅ А функции
concat и concat_ws если какой-то из элементов NULL - проигнорируют его и соединят остальное, но если все NULL - вернут пустую строку. ❗️ Так что будьте осторожны и присоединяйтесь к Симулятору «Аналитик данных», чтобы оценить свои навыки на рабочих кейсах!
#sql
🔥15👍5
📢 [Ласт-колл] на бесплатный live-курс по SQL для начинающих
Это Андрон, основатель IT Resume & Simulative. Просто хочу напомнить, что сегодня в 19:00 по мск пройдет первый день бесплатного live-курса по SQL для начинающих: "Сегментация базы пользователей"
🔗 Чтобы не пропустить трансляцию и получить конспект, переходите по ссылке 👉 https://mnlp.cc/mini?domain=simulative&id=7.
До встречи на трансляции! 😉
Это Андрон, основатель IT Resume & Simulative. Просто хочу напомнить, что сегодня в 19:00 по мск пройдет первый день бесплатного live-курса по SQL для начинающих: "Сегментация базы пользователей"
🔗 Чтобы не пропустить трансляцию и получить конспект, переходите по ссылке 👉 https://mnlp.cc/mini?domain=simulative&id=7.
До встречи на трансляции! 😉
🔥4❤2👍1
🤨 Действительно ли параметр inplace в Pandas ускоряет операции?
Многие пользователи Pandas считают, что использование операций с параметром
🟢 Давайте это проверим
-
-
- И последнее -
Но это лишь предположения, давайте убедимся в них!
🔵 Мы провели небольшой анализ
Смотрите в карточке под постом как некоторые методы работают с
❗️Какие-то методы действительно работают быстрее, некоторые гораздо быстрее, но все-таки большинство - медленнее.
Поэтому, перед тем, как применять
🧠 Если хотите все проверить самостоятельно - делимся ссылкой на коллаб.
#python #pandas
Многие пользователи Pandas считают, что использование операций с параметром
inplace=True ускорит работу с датафреймами. Согласны ли вы с этим? Всегда ли это работает?🟢 Давайте это проверим
Inplace - это параметр методов Pandas, который позволяет изменять DataFrame без создания нового объекта. Звучит так, будто это должно работать быстрее, но есть некоторые нюансы:-
Inplace, вопреки тому, что следует из названия, часто не препятствует созданию копий. Это первый пункт против скорости подобного способа.-
SettingWithCopy - часто получаемое предупреждение - оно не влияет на выполнение кода. Однако же получается Pandas выполняет дополнительные проверки, чтобы убедиться, что датафрейм изменен корректно. Соответственно, второй пункт против скорости inplace.- И последнее -
inplace операции могут быть менее гибкими, так как не позволяют объединить несколько методов в одной строке.Но это лишь предположения, давайте убедимся в них!
🔵 Мы провели небольшой анализ
Смотрите в карточке под постом как некоторые методы работают с
inplace. ❗️Какие-то методы действительно работают быстрее, некоторые гораздо быстрее, но все-таки большинство - медленнее.
Поэтому, перед тем, как применять
inplace, обязательно оцените время и потенциальную пользу в вашем конкретном случае и не потеряйте важные данные!🧠 Если хотите все проверить самостоятельно - делимся ссылкой на коллаб.
#python #pandas
🔥5
🔥 Поговорим о булевых столбцах в PostgreSQL
🤔 Небольшая предыстория. Мы обсуждали со студентами Симулятора «Аналитик данных», что если столбец имеет булевый тип данных и нужно его указать в
И тема развилась до того, что нашелся частный пример: имеется таблица, а в ней булевый столбец со значениями True, False и NULL. И если с выбором отдельных строк с True, False или NULL в данном случае все понятно. Просто пишем:
🟠 То, что делать, если нужно достать строки, со значениями и False, и NULL?
Случился настоящий блиц! Были варианты:
❌
❌
Каков же правильный ответ?
✅ Один из способов - использовать
✅ Еще один абсолютно рабочий вариант:
В PostgreSQL есть 3 состояния для булевого столбца: True, False и неизвестность (NULL). Поэтому нам пригодится только запрос для NOT TRUE:
#sql
🤔 Небольшая предыстория. Мы обсуждали со студентами Симулятора «Аналитик данных», что если столбец имеет булевый тип данных и нужно его указать в
WHERE? Как можно изменить следующий запрос: SELECT col1, col2, col3Надеемся, вы тоже знаете, что достаточно написать
FROM table
WHERE col2 = True;
WHERE column2 если ищем значения True или WHERE NOT column2 если ищем значения False. И тема развилась до того, что нашелся частный пример: имеется таблица, а в ней булевый столбец со значениями True, False и NULL. И если с выбором отдельных строк с True, False или NULL в данном случае все понятно. Просто пишем:
is null -- для выбора только строк со значениями NULL= False / NOT boolean_column -- для выбра строк с False= True / boolean_column -- для выбора строк с True;🟠 То, что делать, если нужно достать строки, со значениями и False, и NULL?
Случился настоящий блиц! Были варианты:
❌
SELECT * FROM table WHERE boolean_column is False or NULL;
Не сработает, так как интерпретируется как (boolean_column is False) or (null). Он возвращает только строки, где boolean_column равна False, так как второе условие всегда ложно.❌
SELECT * FROM table WHERE boolean_column is NULL or False;
Не сработает по той же причине. Интерпретируется как (boolean_column is Null) or (False).Каков же правильный ответ?
✅ Один из способов - использовать
UNION двух запросов, которые по отдельности 100% работают:SELECT * FROM table✅ Можно еще попробовать неординарное COALESCE:
WHERE boolean_column IS NULL
UNION
SELECT * FROM table
WHERE NOT boolean_column
SELECT * FROM table
WHERE NOT COALESCE(boolean_column, False)
Этот запрос заменит все значения NULL на False, а затем выберет все значения False.✅ Еще один абсолютно рабочий вариант:
SELECT * FROM table
WHERE boolean_column is NULL
OR NOT boolean_column
💡 А на самом деле можно просто посмотреть на это с другой стороны:В PostgreSQL есть 3 состояния для булевого столбца: True, False и неизвестность (NULL). Поэтому нам пригодится только запрос для NOT TRUE:
SELECT * FROM table
WHERE boolean_column IS NOT True;
💥 Не бойтесь выходить за рамки стандартного мышления, ведь верных решений может быть сколько угодно!#sql
🔥19👍3❤2
🔥 Переменная цикла и области видимости
Не так давно у нас был пост о том, что переменную цикла нельзя изменить внутри
🤔 Посмотрите на блоки кода ниже и ответьте, что вы получите после выполнения?
Почему переменная цикла обрабатывается по-разному в for-loops и list cоmprehension?
🟢 В цикле
🟠 Но генераторы списков так не работают. Вместо этого переменная цикла всегда остается локальной для генератора списка. Она никогда не утекает «наружу».
#python
Не так давно у нас был пост о том, что переменную цикла нельзя изменить внутри
for-loop. Давайте продолжим тему переменной цикла, но взглянем на нее под другим углом!🤔 Посмотрите на блоки кода ниже и ответьте, что вы получите после выполнения?
a = 1Итак, в первом случае получим
for a in range(6):
pass
print(a)
------------------------
a = 1
[... for a in range(6)]
print(a)
5, а во втором - 1. То есть цикл for обновил существующую переменную a, но генератор списка этого не сделал. Итак, вопрос:Почему переменная цикла обрабатывается по-разному в for-loops и list cоmprehension?
🟢 В цикле
for переменная цикла как бы «утекает» в окружающую область видимости. Другими словами, как только цикл завершится, вы все равно сможете получить доступ к переменной цикла. Убедимся:for loop_var in range(6):Мы могли бы написать даже что-то такое:
pass
print(loop_var)
# 5
b = 1Мы можем получить доступ к переменной цикла вне него и убедиться, что переменная создается и изменяется автоматически.
for a in range(6):
pass
print(a, b)
# 5 1
🟠 Но генераторы списков так не работают. Вместо этого переменная цикла всегда остается локальной для генератора списка. Она никогда не утекает «наружу».
[... for loop_var2 in range(6)]Вот почему существующая переменная a, которая также использовалась внутри генератора списка, осталась неизменной. Генератор списка определил переменную цикла (
print(loop_var2)
# NameError: name 'loop_var2' is not defined
a), локальную для его области видимости.#python
🔥10👍4🤩2
🔥 JOIN по неравенству
Часто вы используете в своей практике
Не осуждаем, это привычный и понятный способ. Но, например, при подсчете промежуточного итога по столбцу если не использовать оконки, как раз нужно джойнить по неравенству. Например, просуммируем всю прибыль полученную до даты сделки:
Что еще можно использовать в таких JOINах? Все операторы сравнения:
🟢 Давайте потренируемся!
У нас есть три таблицы в нашей воображаемой базе данных:
Перечислим дома, которые мы можем предложить нашим арендаторам. Это должны быть дома (1) в предпочтительном районе, (2) в пределах их ценового диапазона, (3) с требуемым количеством спален и (4) не заняты (т.е. не указаны в нашей таблице сделок).
Вот такой запрос с
🔵 Где нам еще может пригодится JOIN по неравенству?
Например, перечислим все дома из нашей базы данных вместе с датой соответствующей сделки (если она есть). Но берем даты только после 1 марта.
Мы получим только два дома, у которых есть даты сделки. А вот написав
🔸 Такие JOINы могут быть очень полезными в разных сценариях, поделитесь с нами вашим опытом использования таких запросов. Часто ли вам приходится с ними сталкиваться?
#sql
Часто вы используете в своей практике
JOIN по неравенству? Думаем, не очень. Обычно все сводится к простому JOIN по равенству, вроде такого: ON t1.column = t2.column, верно?Не осуждаем, это привычный и понятный способ. Но, например, при подсчете промежуточного итога по столбцу если не использовать оконки, как раз нужно джойнить по неравенству. Например, просуммируем всю прибыль полученную до даты сделки:
SELECT s1.date, s1.revenue,
SUM(s2.revenue) AS total
FROM sales s1
JOIN sales s2
ON s1.date >= s2.date
GROUP BY s1.revenue, s1.date
ORDER BY s1.date;
ON s1.date >= s2.date и есть - JOIN по неравенству. Что еще можно использовать в таких JOINах? Все операторы сравнения:
<, >, <=, >=, !=, и <> и оператор BETWEEN.🟢 Давайте потренируемся!
У нас есть три таблицы в нашей воображаемой базе данных:
houses, renters и deals. (См. в карточках 1-2 под постом)Перечислим дома, которые мы можем предложить нашим арендаторам. Это должны быть дома (1) в предпочтительном районе, (2) в пределах их ценового диапазона, (3) с требуемым количеством спален и (4) не заняты (т.е. не указаны в нашей таблице сделок).
Вот такой запрос с
JOIN по неравенству может решить нашу задачу: (См. в карточке 2)🔵 Где нам еще может пригодится JOIN по неравенству?
Например, перечислим все дома из нашей базы данных вместе с датой соответствующей сделки (если она есть). Но берем даты только после 1 марта.
SELECT h.id, h.address,(Результат запроса см. в карточке 3)
d.date
FROM houses h
LEFT JOIN deals d
ON h.id = d.house_id
WHERE d.date >= '2020-03-01';
Мы получим только два дома, у которых есть даты сделки. А вот написав
JOIN по неравенству, все сработает на отлично:SELECT h.id, h.address,(Результат запроса см. в карточке 4)
d.date
FROM houses h
LEFT JOIN deals d
ON h.id = d.house_id
AND d.date >= '2020-03-01';
🔸 Такие JOINы могут быть очень полезными в разных сценариях, поделитесь с нами вашим опытом использования таких запросов. Часто ли вам приходится с ними сталкиваться?
#sql
🔥7👍5❤1