Собесов

Росмэн: прогноз продаж и оборачиваемости с помощью коэффициентов сезонности

PythonПрогнозированиеСредняяJunior

Условие

Даны помесячные продажи и товарный запас по 5 брендам за 2021–2023 (4 мес.) гг.

  1. Сводная таблица «бренд × месяц × год».
  2. Коэффициенты сезонности (по 2021 + 2022).
  3. Прогноз продаж на май–декабрь 2023 для каждого бренда с учётом сезонности.
  4. Оборачиваемость товарного запаса в месяцах.

Решение

Коэффициенты сезонности

Sезон-коэффициент месяца m = mean(sales_m_2021, sales_m_2022) / mean(sales_year).

import pandas as pd, numpy as np
df = pd.read_excel('Sales.xlsx', sheet_name='Sales')
df['Год'] = df.Год.astype(int)
df['Месяц_Num'] = pd.to_datetime(df.Месяц, format='%B').dt.month
 
base = df[df.Год.isin([2021, 2022])]
month_avg = base.groupby(['Бренд','Месяц_Num']).Продажи.mean()
year_avg  = base.groupby('Бренд').Продажи.mean()
seas = (month_avg / year_avg).rename('seas').reset_index()
print(seas.pivot(index='Бренд', columns='Месяц_Num', values='seas'))

Прогноз май–декабрь 2023

Идея: средний месяц 2023 (по январю-апрелю с поправкой на сезонность) умножаем на сезон-коэф каждого месяца.

known_2023 = df[(df.Год==2023)]
# «Расшумленный» базовый уровень: divide by seas
base_2023 = known_2023.merge(seas, on=['Бренд','Месяц_Num'])
base_2023['adj'] = base_2023.Продажи / base_2023.seas
base_per_brand = base_2023.groupby('Бренд').adj.mean()    # стационарный уровень
 
forecast_months = list(range(5, 13))
forecast_rows = []
for brand, lvl in base_per_brand.items():
    for m in forecast_months:
        s = seas[(seas.Бренд==brand)&(seas.Месяц_Num==m)].seas.iloc[0]
        forecast_rows.append({'Бренд':brand, 'Месяц':m, 'Прогноз': lvl * s})
fc = pd.DataFrame(forecast_rows)

Оборачиваемость

Оборачиваемость в месяцах = средний запас / продажи в месяц.

df['Оборач'] = df['Товарныйзапаснаконецпериода'] / df.Продажи
piv = df.pivot(index=['Бренд','Год'], columns='Месяц_Num', values='Оборач')

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

  1. Коэф сезонности на 2 годах нестабилен — особенно для брендов 4 и 5, появившихся в 2022. Для них сезонность считать нечего.
  2. У Бренда 4 в 2023 продажи резко падают (Янв 61 после Дек 360) — возможно, бренд снимается с продаж. Прогноз будет дико переоценён.
  3. Декабрь — пиковый месяц (праздники), коэф ~3–4. Не путать сезон с трендом.
  4. Оборачиваемость по запасу на конец периода может быть отрицательной, если продали больше, чем привезли. NULLIF обязательно.
  5. Лучшая практика — Holt-Winters или SARIMA вместо «среднего × сезон».

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

Коэф. сезонности по 2021–2022 → базовый уровень 2023 = avg(known/seas) → прогноз = base × seas. Оборачиваемость = stock / sales.

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

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

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