Какое распределение нагрузки службы доставки еды в течение дня?

«Какое распределение нагрузки службы доставки еды в течение дня?» — вопрос из категории Временные ряды, который задают на 26% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нагрузка службы доставки еды в течение суток имеет ярко выраженный неравномерный характер с несколькими пиками, который можно смоделировать как полимодальное временное распределение. Основные закономерности для буднего дня в крупном городе:

  • Утренний спад (00:00 – 10:00): Минимальная активность, заказы редкие (ночные смены, поздние вечеринки).
  • Рост к обеду (10:00 – 12:00): Активность начинает расти.
  • Обеденный пик (12:00 – 14:00): Максимальная нагрузка, связанная с перерывом на работе.
  • Послеобеденный спад (14:00 – 17:00): Относительное затишье.
  • Вечерний пик (18:00 – 21:00): Второй, часто более высокий и продолжительный пик, связанный с ужином после рабочего дня.
  • Вечерний спад (после 22:00): Активность постепенно снижается до ночного минимума.

Факторы, влияющие на распределение:

  • День недели: В пятницу и субботу вечерний пик выше и длиннее, смещён в сторону более позднего времени.
  • Погода: В дождливую или холодную погода количество заказов увеличивается.
  • Локация: В бизнес-районах выражен обеденный пик, в жилых — вечерний.
  • Сезонность и праздники.

Пример анализа временного ряда заказов (Python с pandas):

import pandas as pd
import matplotlib.pyplot as plt

# Предположим, у нас есть DataFrame `orders` с колонкой 'order_time'
# Агрегируем количество заказов по часам
orders['hour'] = orders['order_time'].dt.hour
hourly_load = orders.groupby('hour').size()

plt.figure(figsize=(10,5))
plt.plot(hourly_load.index, hourly_load.values, marker='o')
plt.fill_between(hourly_load.index, 0, hourly_load.values, alpha=0.3)
plt.xlabel('Час дня')
plt.ylabel('Количество заказов')
plt.title('Суточное распределение нагрузки службы доставки')
plt.grid(True, linestyle='--', alpha=0.7)
plt.xticks(range(0,24))
plt.show()