← Назад к вопросам

Как работает агрегация данных в Pandas? Объясните методы groupby и agg.?

1.0 Junior🔥 261 комментариев
#Python и инструменты

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Агрегация данных в Pandas: groupby и agg

Pandas — это мощная библиотека для обработки данных в Python. Методы groupby и agg — это основные инструменты для агрегации и группировки данных, эквивалентные GROUP BY в SQL.

Основы groupby

метод groupby() разбивает DataFrame на группы по одному или нескольким столбцам, позволяя затем применить функции агрегации.

Синтаксис:

df.groupby(by).agg(функция)

Простой пример:

import pandas as pd

# Создаем DataFrame
df = pd.DataFrame({
    'country': ['US', 'US', 'UK', 'UK', 'DE', 'DE'],
    'user_id': [1, 2, 3, 4, 5, 6],
    'revenue': [100, 150, 200, 175, 120, 140]
})

# Группируем по стране и считаем средний доход
result = df.groupby('country')['revenue'].mean()
print(result)
# country
# DE    130.0
# UK    187.5
# US    125.0

Основные агрегатные функции

Встроенные функции:

import pandas as pd

df = pd.DataFrame({
    'country': ['US', 'US', 'UK', 'UK'],
    'revenue': [100, 150, 200, 175],
    'created_at': ['2024-01-01', '2024-01-02', '2024-01-01', '2024-01-03']
})

# Различные агрегации
agg_results = df.groupby('country').agg({
    'revenue': ['sum', 'mean', 'min', 'max', 'count'],  # несколько функций
    'created_at': ['min', 'max']                         # первая и последняя дата
})

print(agg_results)
#          revenue                         created_at
#            sum  mean  min  max count          min          max
# country
# UK       375  187.5  175  200     2  2024-01-01  2024-01-03
# US       250  125.0  100  150     2  2024-01-01  2024-01-02

Полный список встроенных функций:

  • sum() — сумма
  • mean() — среднее
  • median() — медиана
  • std() — стандартное отклонение
  • min() — минимум
  • max() — максимум
  • count() — количество
  • first() — первое значение
  • last() — последнее значение

Использование метода agg()

метод agg() позволяет применять одну или несколько функций к каждой группе.

Пример 1: Несколько функций к одному столбцу

df = pd.DataFrame({
    'category': ['A', 'A', 'B', 'B'],
    'value': [10, 20, 30, 40]
})

# Несколько функций
result = df.groupby('category')['value'].agg(['sum', 'mean', 'count'])
print(result)
#    sum  mean  count
# A   30  15.0      2
# B   70  35.0      2

Пример 2: Разные функции для разных столбцов

df = pd.DataFrame({
    'country': ['US', 'US', 'UK', 'UK'],
    'revenue': [100, 150, 200, 175],
    'users': [10, 15, 20, 18]
})

# Разные функции для разных столбцов
result = df.groupby('country').agg({
    'revenue': 'sum',      # Сумма доходов
    'users': 'mean'        # Средний размер
})

print(result)
#    revenue  users
# UK      375   19.0
# US      250   12.5

Пример 3: Именованные агрегации (новый способ)

# Новый способ (Pandas >= 0.25)
result = df.groupby('country').agg(
    total_revenue=('revenue', 'sum'),
    avg_revenue=('revenue', 'mean'),
    num_users=('users', 'count')
)

print(result)
#    total_revenue  avg_revenue  num_users
# UK            375       187.5          2
# US            250       125.0          2

Практические примеры для Product Analytics

Пример 1: Анализ конверсии по дням

import pandas as pd

df = pd.DataFrame({
    'date': ['2024-01-01', '2024-01-01', '2024-01-02', '2024-01-02', 
             '2024-01-02', '2024-01-03'],
    'user_id': [1, 2, 1, 3, 4, 5],
    'converted': [False, True, True, False, True, True]
})

# Конверсия по дням
result = df.groupby('date').agg({
    'user_id': 'count',                                    # Всего событий
    'converted': ['sum', lambda x: (x.sum() / len(x))]
}).round(3)

result.columns = ['total_events', 'conversions', 'conversion_rate']
print(result)
#             total_events  conversions  conversion_rate
# 2024-01-01             2            1            0.500
# 2024-01-02             3            2            0.667
# 2024-01-03             1            1            1.000

Пример 2: RFM анализ

import pandas as pd
from datetime import datetime

df = pd.DataFrame({
    'user_id': [1, 1, 2, 2, 3, 3],
    'purchase_date': ['2024-01-01', '2024-01-15', '2024-01-05', '2024-02-10',
                      '2024-01-10', '2024-01-20'],
    'amount': [100, 150, 200, 50, 75, 125]
})

df['purchase_date'] = pd.to_datetime(df['purchase_date'])
today = pd.to_datetime('2024-02-20')

# RFM анализ
rfm = df.groupby('user_id').agg({
    'purchase_date': lambda x: (today - x.max()).days,  # Recency
    'user_id': 'count',                                  # Frequency
    'amount': 'sum'                                       # Monetary
})

rfm.columns = ['recency', 'frequency', 'monetary']
print(rfm)
#   recency  frequency  monetary
# 1        6          2       250
# 2        9          2       250
# 3       31          2       200

Пример 3: Когортный анализ (retention)

import pandas as pd

df = pd.DataFrame({
    'user_id': [1, 1, 2, 2, 2, 3],
    'signup_date': ['2024-01-01', '2024-01-01', '2024-01-05', '2024-01-05',
                    '2024-01-05', '2024-01-10'],
    'activity_date': ['2024-01-01', '2024-01-15', '2024-01-05', '2024-01-12',
                      '2024-02-05', '2024-01-10']
})

df['signup_date'] = pd.to_datetime(df['signup_date'])
df['activity_date'] = pd.to_datetime(df['activity_date'])

# Days since signup
df['days_since_signup'] = (df['activity_date'] - df['signup_date']).dt.days

# Группируем по когортам
cohort = df.groupby('signup_date').agg({
    'user_id': 'nunique',           # Размер когорты
    'days_since_signup': 'mean'     # Средние дни активности
})

cohort.columns = ['cohort_size', 'avg_days_active']
print(cohort)
#             cohort_size  avg_days_active
# 2024-01-01            1                8.0
# 2024-01-05            2               24.5
# 2024-01-10            1                0.0

Пользовательские функции (Custom Functions)

Можно применять свои функции в agg().

Пример 4: Стандартные ошибки и доверительные интервалы

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'group': ['A', 'A', 'A', 'B', 'B', 'B'],
    'value': [10, 12, 11, 20, 22, 19]
})

def confidence_interval(x, confidence=0.95):
    """Расчет доверительного интервала"""
    se = np.std(x) / np.sqrt(len(x))
    margin = se * 1.96  # Для 95%
    return f"{x.mean():.2f} ± {margin:.2f}"

result = df.groupby('group')['value'].agg(
    mean='mean',
    std='std',
    count='count',
    ci=confidence_interval
)

print(result)
#   mean       std  count        ci
# A   11  1.0  3  11.00 ± 1.96
# B   20  1.41      3  20.67 ± 2.23

Пример 5: Применение нескольких пользовательских функций

import pandas as pd

df = pd.DataFrame({
    'category': ['X', 'X', 'Y', 'Y'],
    'revenue': [100, 150, 200, 180]
})

def range_stat(x):
    """Диапазон (max - min)"""
    return x.max() - x.min()

def cv(x):
    """Коэффициент вариации"""
    return x.std() / x.mean()

result = df.groupby('category')['revenue'].agg([
    ('mean', 'mean'),
    ('std', 'std'),
    ('range', range_stat),
    ('cv', cv)
]).round(3)

print(result)
#        mean   std  range     cv
# category
# X      125.0  35.36   50  0.283
# Y      190.0   10.0   20  0.053

Множественная группировка

Пример 6: GROUP BY с несколькими столбцами

import pandas as pd

df = pd.DataFrame({
    'country': ['US', 'US', 'UK', 'UK'],
    'device': ['mobile', 'desktop', 'mobile', 'desktop'],
    'revenue': [100, 150, 200, 175]
})

# Группировка по двум столбцам
result = df.groupby(['country', 'device']).agg({
    'revenue': ['sum', 'mean']
}).round(2)

print(result)
#                    revenue
#                       sum   mean
# country device
# UK      desktop      175  175.0
#         mobile       200  200.0
# US      desktop      150  150.0
#         mobile       100  100.0

Фильтрация групп (filter)

Пример 7: Оставить только группы с условием

import pandas as pd

df = pd.DataFrame({
    'user_id': [1, 1, 2, 2, 3],
    'purchase_value': [100, 150, 50, 75, 200]
})

# Оставляем только пользователей с суммой > 150
result = df.groupby('user_id').filter(lambda x: x['purchase_value'].sum() > 150)

print(result)
#   user_id  purchase_value
# 0        1             100
# 1        1             150
# 2        3             200

Performance и Memory

# Для больших файлов используй category dtype
df['country'] = df['country'].astype('category')

# Или используй SQL напрямую
import sqlite3
connection = sqlite3.connect(':memory:')
df.to_sql('data', connection, if_exists='replace')
result = pd.read_sql_query('SELECT country, SUM(revenue) FROM data GROUP BY country', connection)

Чек-лист использования groupby и agg

  • Выбраны правильные столбцы для группировки
  • Все необходимые агрегации добавлены
  • Результаты отсортированы логично
  • Проверены NULL значения и пустые группы
  • Названия столбцов понятны
  • Для больших данных используется эффективный способ
  • Результаты валидированы (сравнены с SQL)

groupby и agg — это базовые инструменты для анализа данных в Pandas, аналогичные GROUP BY в SQL.