Мир аналитика данных
@analysts_world
Я про вас не забыла и вот принесла кое-что интересное. Телегу замедляют, но я остаюсь тут и не хочу предлагать вам куда-то переходить. Поддержите огонечками, что вы тут и вам это по прежнему нужно!
Сегодня хочу показать удобный SQL-прием для A/B тестов: как смотреть метрику сразу по нескольким двухнедельным периодам и не размечать каждый интервал руками. Так легче заметить, метрика стабильна или скачет от периода к периоду.
В этом примере считаем такую метрику: доля пользователей, которые открыли карточку товара из целевого блока, среди всех пользователей, открывших карточку товара за период.
Логика очень простая:
берем всех уникальных пользователей, открывших карточку товара
отдельно считаем тех, кто пришел в карточку из блока Подборка для вас
делим второе на первое и получаем долю
Сгенерировала df_product_events(event_ts, user_id, event_name, event_payload).
Самая важная часть здесь - это расчет period_start (каждому событию назначается начало его двухнедельного периода)
Что здесь происходит:
Берем опорную дату, с которой хотим начать нарезку периодов
Через date_diff считаем, сколько дней прошло от нее до события
Делим это число на 14.0, чтобы понять, в какой двухнедельный интервал попало событие.
Через floor округляем вниз, чтобы получить номер двухнедельного интервала
потом умножаем на 14 и прибавляем к опорной дате через date_add
В итоге каждое событие автоматически попадает в нужное окно.
Например, если опорная дата - 2026-02-02, то:
событие от 2026-02-03 попадет в период с началом 2026-02-02
событие от 2026-02-14 тоже попадет туда же
а событие от 2026-02-16 уже уйдет в следующий период
Дальше все обычно: по каждому периоду считаем всех уникальных пользователей карточки товара, отдельно - пользователей из целевого блока, и получаем долю.
Мне нравится этот способ тем, что он очень легко масштабируется. Не нужно руками прописывать периоды через case when, не нужно собирать отдельные запросы под каждое окно. Один раз задали опорную дату и длину периода - и дальше запрос сам аккуратно раскладывает события как надо.
Если нужно смотреть метрику не по 14 дням, а, например, по трем неделям, меняется одно число и все. Удобно же!
В ноутбуке я еще отдельно оформила формулировку метрики в виде плашки зеленого цвета - так что можно заглянуть не только за SQL, но и за кодом такой вставки. Отделять метрику от метрики в огромных скриптах очень удобно!
Сегодня хочу показать удобный SQL-прием для A/B тестов: как смотреть метрику сразу по нескольким двухнедельным периодам и не размечать каждый интервал руками. Так легче заметить, метрика стабильна или скачет от периода к периоду.
В этом примере считаем такую метрику: доля пользователей, которые открыли карточку товара из целевого блока, среди всех пользователей, открывших карточку товара за период.
Логика очень простая:
берем всех уникальных пользователей, открывших карточку товара
отдельно считаем тех, кто пришел в карточку из блока Подборка для вас
делим второе на первое и получаем долю
Сгенерировала df_product_events(event_ts, user_id, event_name, event_payload).
import duckdb
import pandas as pd
query = """
with events as (
select
date_add(
date '2026-02-02',
INTERVAL (cast(14 * floor(date_diff('day', date '2026-02-02', cast(event_ts as date)) / 14.0) as integer)) DAY) as period_start,
user_id,
json_extract_string(event_payload, '$.source_block') as source_block
from df_product_events
where event_ts >= timestamp '2026-02-02 00:00:00'
and event_ts < timestamp '2026-03-16 00:00:00'
and event_name = 'product_card_open'
and nullif(trim(user_id), '') is not null
)
select
period_start,
period_start + INTERVAL 13 DAY as period_end,
count(distinct user_id) as users_total,
count(distinct case when source_block = 'Подборка для вас' then user_id end) as users_from_target_block,
round(
100.0 * count(distinct case when source_block = 'Подборка для вас' then user_id end)
/ count(distinct user_id),
2
) as share_from_target_block
from events
group by 1, 2
order by 1
"""
result = duckdb.query(query).to_df()Самая важная часть здесь - это расчет period_start (каждому событию назначается начало его двухнедельного периода)
Что здесь происходит:
Берем опорную дату, с которой хотим начать нарезку периодов
Через date_diff считаем, сколько дней прошло от нее до события
Делим это число на 14.0, чтобы понять, в какой двухнедельный интервал попало событие.
Через floor округляем вниз, чтобы получить номер двухнедельного интервала
потом умножаем на 14 и прибавляем к опорной дате через date_add
В итоге каждое событие автоматически попадает в нужное окно.
Например, если опорная дата - 2026-02-02, то:
событие от 2026-02-03 попадет в период с началом 2026-02-02
событие от 2026-02-14 тоже попадет туда же
а событие от 2026-02-16 уже уйдет в следующий период
Дальше все обычно: по каждому периоду считаем всех уникальных пользователей карточки товара, отдельно - пользователей из целевого блока, и получаем долю.
Мне нравится этот способ тем, что он очень легко масштабируется. Не нужно руками прописывать периоды через case when, не нужно собирать отдельные запросы под каждое окно. Один раз задали опорную дату и длину периода - и дальше запрос сам аккуратно раскладывает события как надо.
Если нужно смотреть метрику не по 14 дням, а, например, по трем неделям, меняется одно число и все. Удобно же!
В ноутбуке я еще отдельно оформила формулировку метрики в виде плашки зеленого цвета - так что можно заглянуть не только за SQL, но и за кодом такой вставки. Отделять метрику от метрики в огромных скриптах очень удобно!
🔥 37
❤🔥 26
❤ 4
3 19 1.3K
Обсуждение 3
Обсуждение не доступно в веб-версии. Чтобы написать комментарий, перейдите в приложение Telegram.
Обсудить в Telegram