Нашли ошибку?
Скачать чистый
мини-проект≈ 20 минупражнения: 0 из 6

Мини-проект: погода и продажи

Зависят ли продажи чая от погоды? Ставим дневные продажи рядом с температурой, измеряем связь корреляцией и смотрим, как она меняется, если перейти от дней к неделям и месяцам.

Python запустится при первом выполнении

Владелец «Кофейной лавки» уверен: в холод чай покупают охотнее. Если это так, по прогнозу погоды можно планировать закупки. Проверим на данных одного города — возьмём продажи в Москве и московскую погоду. В проекте один новый метод — corr, остальное — приёмы этого модуля.

[ ]Продажи в Москве и погода в Москве
import pandas as pd

orders = pd.read_csv("data/shop_orders.csv", parse_dates=["date"])
orders["revenue"] = orders["price"] * orders["quantity"]
msk = orders[orders["city"] == "Москва"]
weather = pd.read_csv("data/weather.csv", parse_dates=["date"])
moscow = weather[weather["city"] == "Москва"].set_index("date")
print(len(msk), len(moscow))
moscow.head(3)
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
948 365
city temp_min temp_max precip_mm wind_ms
date
2025-01-01 Москва -9.9 -3.2 0.0 1.9
2025-01-02 Москва -9.7 -3.2 0.0 2.3
2025-01-03 Москва -9.0 -3.7 0.0 5.2

Шаг 1. Продажи по дням

[ ]Упражнение 1Два ряда с полным календарём решено

По таблице msk соберите два ряда, приведённых к календарю calendar (в дни без продаж — ноль): total — выручка за день, tea — выручка за день только от товаров категории «Чай».

calendar = pd.date_range("2025-01-01", "2025-12-31")
total = ...
tea = ...

Шаг 2. Погода и продажи рядом

У рядов total и tea и у таблицы moscow одинаковый индекс — дни года. Значит, их можно поставить рядом, и pandas сам сопоставит строки по датам.

[ ]Упражнение 2Одна таблица решено

Соберите таблицу data из четырёх столбцов: temp — temp_max из moscow, rain — precip_mm из moscow, tea и total — ряды из шага 1. В gaps сохраните число пропусков в каждом столбце.

data = ...
gaps = ...

Шаг 3. Как измерить связь

«Чем холоднее, тем больше чая» — это утверждение о связи двух величин. Её силу измеряет коэффициент корреляции — число от −1 до 1:

  • около 1 — величины растут вместе;
  • около −1 — одна растёт, другая падает;
  • около 0 — линейной связи нет.

Метод corr считает его для двух Series:

[ ]Рост и вес, рост и что-то убывающее, рост и случайные числа
height = pd.Series([150, 160, 170, 180, 190])
print(round(height.corr(pd.Series([50, 58, 66, 75, 84])), 3))
print(round(height.corr(pd.Series([9, 8, 6, 5, 3])), 3))
print(round(height.corr(pd.Series([4, 9, 2, 8, 5])), 3))
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
1.0
-0.993
0.055

Первая пара растёт вместе — почти 1. Вторая — в противоположные стороны, почти −1. Третья — случайные числа, и коэффициент близок к нулю.

[ ]Упражнение 3Связь по дням решено

Сохраните в r_day корреляцию температуры (temp) и выручки от чая (tea) по дням. В r_rain — корреляцию осадков (rain) и общей выручки (total).

r_day = ...
r_rain = ...

Минус есть — в тёплые дни чая продают меньше, — но связь слабая: −0.17. А между осадками и выручкой линейной связи не видно: 0.06. (В столбце rain один пропуск — corr такую пару значений просто не учитывает.) Выходит, владелец ошибался?

Не спешите. В половине дней чай в Москве вообще не покупали — дневные продажи очень «шумные»: всё решает случай. Шум заглушает закономерность.

Пояснение с ответом появится, когда решите упражнение «Связь по дням».

Шаг 4. От дней к неделям

Случайности разных дней гасят друг друга, если сложить дни в недели.

[ ]Упражнение 4Связь по неделям решено

Сохраните в weekly таблицу по полным неделям: temp — средняя температура недели, tea — выручка от чая за неделю. В r_week сохраните корреляцию этих двух столбцов.

weekly = ...
r_week = ...

Шаг 5. От недель к месяцам

[ ]Упражнение 5Связь по месяцам решено

Сохраните в monthly такую же таблицу по месяцам, округлённую до одного знака. В r_month — корреляцию temp и tea, в tea_peak — номер месяца с наибольшей выручкой от чая.

monthly = ...
r_month = ...
tea_peak = ...

[ ]Температура и чай по месяцам
monthly
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
temp tea
2025-01-31 -3.8 27400
2025-02-28 -4.7 26300
2025-03-31 1.6 17910
2025-04-30 10.9 11600
2025-05-31 15.5 8630
2025-06-30 20.1 18940
2025-07-31 21.7 10110
2025-08-31 21.6 19580
2025-09-30 16.0 17040
2025-10-31 10.2 10450
2025-11-30 2.1 27610
2025-12-31 -2.6 35120
Вывод появится, когда решите упражнение «Связь по месяцам», — иначе он подскажет ответ. Ячейку можно и выполнить.

Теперь связь видна и без коэффициента: в морозные месяцы чая продают на 26–35 тысяч, в тёплые — на 9–20.

Пояснение с ответом появится, когда решите упражнение «Связь по месяцам».

Шаг 6. Морозные, прохладные и тёплые дни

Другой способ увидеть ту же связь — без корреляции. Разделим дни на три группы по температуре и сравним средние.

[ ]Упражнение 6Чай по температурным группам решено

Добавьте в data столбец band — группу дня по temp: до 0 — «мороз», до 15 — «прохладно», выше — «тепло» (границы [-50, 0, 15, 50]). Сохраните в tea_by_band среднюю дневную выручку от чая в каждой группе, округлённую до одного знака.

# добавьте в data столбец band
tea_by_band = ...

Шаг 7. Сезон или погода?

Остался главный вопрос владельца: поможет ли прогноз погоды? Чай хорошо продаётся в холодные месяцы — но, может быть, дело просто во времени года? Проверим, что происходит внутри месяца: вычтем из температуры и из продаж чая их средние за свой месяц (это transform из модуля о группировке) и посмотрим, связаны ли отклонения.

[ ]Корреляция отклонений от среднего за месяц
data["month"] = data.index.month
temp_dev = data["temp"] - data.groupby("month")["temp"].transform("mean")
tea_dev = data["tea"] - data.groupby("month")["tea"].transform("mean")
print(round(temp_dev.corr(tea_dev), 2))
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
0.05

Почти ноль. День, который холоднее обычного для своего месяца, продаж чая не прибавляет.

Итог

[ ]Что получилось
print("Корреляция температуры и продаж чая:")
print("  по дням   ", round(r_day, 2))
print("  по неделям", round(r_week, 2))
print("  по месяцам", round(r_month, 2))
print("Осадки и выручка:", round(r_rain, 2))
print(tea_by_band)
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
Корреляция температуры и продаж чая:
  по дням    -0.17
  по неделям -0.41
  по месяцам -0.7
Осадки и выручка: 0.06
band
мороз        913.7
прохладно    544.3
тепло        489.4
Name: tea, dtype: float64
Итог появится, когда решите все упражнения урока, — в нём ответы. Ячейку можно и выполнить.

Выводы

  • В холодные месяцы чая покупают больше. В морозный день — в среднем на 914 ₽, в тёплый — на 489 ₽, почти вдвое меньше.
  • Связь тем заметнее, чем крупнее период: −0.17 по дням, −0.41 по неделям, −0.70 по месяцам. Данные те же — укрупнение убирает дневной шум и оставляет сезон, а связь, как показал шаг 7, сезонная.
  • Но эта связь — сезонная. Внутри месяца её нет (0.05): погода конкретного дня сверх времени года ничего не добавляет. Планировать закупки чая стоит по календарю, а не по прогнозу погоды.
  • Между осадками и выручкой линейной связи в данных не видно: 0.06.
Выводы с ответами появятся, когда решите все упражнения урока.

И два предостережения о корреляции — наш проект показал оба.

Корреляция — не причина. Температура и продажи чая меняются вместе, потому что обе зависят от времени года: в декабре холодно — и в декабре же покупают подарки к Новому году. Мы увидели это, когда убрали сезон: связь исчезла. Общая причина, которая двигает обе величины, — самое частое объяснение «красивой» корреляции.

Ноль — не значит «связи нет». Коэффициент ловит только связь вида «больше — больше» или «больше — меньше». Если продажи высоки и в мороз, и в жару, а посередине низкие, корреляция будет около нуля — хотя связь есть. Поэтому про осадки мы говорим осторожно: «линейной связи не видно».

Подробнее в справочнике

Практика по модулю

Задачи по pandas для самостоятельной практики появятся в разделе «Задачи → pandas».

Нашли ошибку?