Собесов

Сценарий: melt — перевод широкой таблицы в длинную

PythonPandas базовый workflowЛёгкаяJunior

Условие

В Excel прислали отчёт: колонки user_id, plan, 2024-01, 2024-02, ..., 2024-12 — по месяцам в каждой колонке выручка. Нужно перевести в «длинный» (tidy) формат: user_id, plan, month, revenue.

Решение

Подход

pd.melt (или метод df.melt) переводит набор «широких» колонок в две: имя переменной (var_name) и значение (value_name). Остальные колонки идут в id_vars.

Реализация

import pandas as pd
 
long = df.melt(
    id_vars=['user_id', 'plan'],
    value_vars=[c for c in df.columns if c.startswith('2024-')],
    var_name='month',
    value_name='revenue',
)
 
# Превратить строку '2024-03' в дату:
long['month'] = pd.to_datetime(long['month'] + '-01')
 
# Убрать пустые ячейки (если в широком формате они были NaN):
long = long.dropna(subset=['revenue'])

Обратная операция

wide = long.pivot_table(
    index=['user_id', 'plan'],
    columns='month',
    values='revenue',
    aggfunc='sum',
).reset_index()

Подводные камни

  1. Если value_vars не задан — melt расплавит все не-id_vars колонки, в том числе те, что не должны были туда попасть.
  2. Типы данных в широких колонках смешанные (int+NaN → float) — после melt колонка revenue тоже станет float; нужно astype руками.
  3. Имя месяца как строка плохо сортируется ('2024-10' < '2024-2'), всегда переводите в datetime.
  4. Дубли по (user_id, plan, month) после melt означают, что в широком формате не была обеспечена уникальность — проверять duplicated().sum().
  5. Для нескольких метрик (revenue + clicks) удобнее pd.wide_to_long с stub-именами.

Эталонный ответ

df.melt(id_vars=[...], value_vars=[...], var_name='month', value_name='revenue') — переводит «колонки-месяцы» в строки.

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти