**Контекст:** Социальная сеть проводит A/B-тест и анализирует активность пользователей в двух группах за 14 дней.
**Данные:** DataFrame `user_activity` — колонки: `user_id`, `group` (A/B), `day` (1–14), `messages_sent`, `time_spent_min`.
**Задание:**
1. Для каждого пользователя рассчитайте кумулятивную сумму сообщений по дням (`transform`)
2. Рассчитайте среднедневную активность по группам (`groupby` + `agg`)
3. Вычислите отклонение каждого дня от пользовательского среднего (`transform`)
4. Сравните группы A и B
Структура для ориентира — реальные значения из эталонного решения.
import pandas as pd
import numpy as np
np.random.seed(42)
n_users = 500
days = 14
rows = []
for uid in range(n_users):
group = 'A' if uid < 250 else 'B'
base_msg = np.random.poisson(8 if group == 'A' else 10)
base_time = np.random.normal(25 if group == 'A' else 30, 5)
for d in range(1, days + 1):
rows.append({
'user_id': uid, 'group': group, 'day': d,
'messages_sent': max(0, base_msg + np.random.randint(-3, 4)),
'time_spent_min': round(max(1, base_time + np.random.normal(0, 3)), 1),
})
df = pd.DataFrame(rows)
# 1. Кумулятивная сумма сообщений (по пользователю)
df['cum_messages'] = df.groupby('user_id')['messages_sent'].transform('cumsum')
# 2. Среднее время пользователя (broadcast обратно в каждую строку)
df['user_avg_time'] = df.groupby('user_id')['time_spent_min'].transform('mean')
# 3. Отклонение от среднего пользователя
df['time_deviation'] = (df['time_spent_min'] - df['user_avg_time']).round(1)
print("Пример данных (user_id=0):")
print(df[df['user_id'] == 0][['day', 'messages_sent', 'cum_messages',
'time_spent_min', 'user_avg_time', 'time_deviation']].head(7))
# 4. Сравнение групп через agg
group_stats = df.groupby('group').agg(
avg_messages=('messages_sent', 'mean'),
avg_time=('time_spent_min', 'mean'),
total_messages=('messages_sent', 'sum'),
users=('user_id', 'nunique'),
).round(2)
print("\nСравнение групп:")
print(group_stats)
# 5. Динамика по дням через apply
def daily_summary(grp):
return pd.Series({
'avg_messages': grp['messages_sent'].mean(),
'p95_time': grp['time_spent_min'].quantile(0.95),
})
daily_by_group = df.groupby(['group', 'day']).apply(daily_summary).round(1)
print("\nДинамика по дням (первые 5 дней):")
print(daily_by_group.head(10))
pandas apply transform groupby лямбда-функции
Это задание для уровня Junior. Подходит для начинающих аналитиков, проверяет базовые знания SQL/Python/статистики.
Подобные задания в категории «Python» регулярно дают на собеседованиях аналитика данных в Яндекс, Сбер, Ozon, Авито, Тинькофф, Wildberries, T-Bank, X5, ВТБ и других крупных IT-компаниях. Тематика: pandas, apply, transform, groupby, лямбда-функции.
На реальном собеседовании на подобную задачу отводится 5-10 минут — проверяется скорость и базовая грамотность. Для тренировки рекомендуем сначала решить самостоятельно, потом сверить с эталонным решением и подсказками.
На zasqlpython.ru есть 482 Python задачи с проверкой через Pyodide, конспекты Python и pandas, AI мок-собеседование с разбором ваших ответов.
← Все задания