Я понимаю - пятница, но я обещала дать расчет как можно решить задачку с собеса другим способом. Вдруг в выходные захочется потренироваться? 😜
Мы брали топ 5% пользователей по порядковому номеру (row_number).
Этот способ особенно полезен, когда важно выделить пользователей, которые попадают в верхнюю часть распределения по значению, а не просто занимают первые 5% позиций в сортировке.
📌 Что такое квантиль?
Квантиль — это значение, “разрезающее” распределение данных на доли.
95-й квантиль (0.95) — это число, ниже которого лежит 95% всех значений.
Соответственно, всё, что равно или выше этого порога, — это верхние 5% распределения.
👉 Это и есть математическое определение топ 5% по значению, а не по рангу.
📘 Пример на наших цифрах. Методика расчёта квантиля, чтобы понимать саму теорию
У нас есть количество заказов по пользователям cnt, всего 20 значений.
1️⃣Сортируем 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4(тут лень вписывать имена), 6(Алиса), 8(Саша), 10(Ева)
95-й квантиль = 10
Значит, в топ-5% попадут пользователи с количеством заказов ≥ 9.
2️⃣ Находим позицию квантиля
Используем формулу: k=p×n, где p — нужный квантиль (для 95% это 0.95), n — размер массива.
𝑘=0.95×20=19
3️⃣ Берём k-ый, то есть 19-й элемент = 8. 📌 Значит, 95-й квантиль = 8
Это значит - 95% пользователей сделали ≤ 8 заказов.
А значит топ 5% — это те, у кого 👉 cnt > 8 Это как раз одна Ева с кол-вом заказов cnt = 10
🧩 Ну и код, не в ручную же считать, когда у нас sql есть. Используем approx_quantile
query = """
with user_orders as (
select u.user_id, u.name, count(o.order_id) as cnt
from users u
left join orders o on u.user_id = o.user_id
group by u.user_id, u.name
),
threshold as (
select approx_quantile(cnt, 0.95) as p95
from user_orders
)
select user_id, name, cnt
from user_orders uo
cross join threshold t
where uo.cnt > t.p95
"""
result = duckdb.query(query).to_df()
🎯 Итог
Существуют разные определения квантилей (в numpy, R, SQL, Spark, Excel — свои методы).
Но в задачах на собеседования чаще всего используют именно эту базовую методику