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

Итоговый проект: отчёт

Отчёт о годе «Кофейной лавки» по собранной таблице: динамика по месяцам, прибыль и возвраты по категориям, города и средний чек, сводная «категории × города», сегменты и лучшие покупатели, графики и выводы.

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

Вторая часть итогового проекта. Таблица собрана — теперь нужно ответить на вопросы владельца: как шёл год, на чём магазин зарабатывает, где и кому продаёт. В отчёте везде используется чистая выручка net — за вычетом возвратов.

Первая ячейка заново собирает таблицу из прошлого урока — то же самое, записанное тремя цепочками, плюс один новый столбец: month, номер месяца. Прочитайте её: каждая строка вам знакома.

[ ]Рабочая таблица: 2448 строк, 17 столбцов
import pandas as pd

short = {"Спб": "Санкт-Петербург", "С.-Петербург": "Санкт-Петербург", "Екб": "Екатеринбург"}
customers = (
    pd.read_csv("data/customers_raw.csv")
    .assign(
        customer_id=lambda d: d["customer_id"].str.strip().str.upper(),
        city=lambda d: d["city"].str.strip().str.title().replace(short),
        segment=lambda d: d["segment"].str.strip().str.lower(),
    )
    [["customer_id", "city", "segment"]]
    .drop_duplicates()
)
returns = (
    pd.read_csv("data/returns_raw.csv")
    .drop_duplicates()
    .drop_duplicates(subset=["order_id", "product_id"])
    [["order_id", "product_id", "quantity"]]
    .rename(columns={"quantity": "returned"})
)
data = (
    pd.read_csv("data/orders.csv", parse_dates=["date"])
    .merge(pd.read_csv("data/products.csv"), on="product_id", validate="many_to_one")
    .merge(customers, on="customer_id", validate="many_to_one")
    .merge(returns, on=["order_id", "product_id"], how="left", validate="one_to_one")
    .assign(
        returned=lambda d: d["returned"].fillna(0).astype("int64"),
        revenue=lambda d: d["price"] * d["quantity"],
        net=lambda d: d["price"] * (d["quantity"] - d["returned"]),
        profit=lambda d: (d["price"] - d["cost"]) * (d["quantity"] - d["returned"]),
        month=lambda d: d["date"].dt.month,
    )
)
print(data.shape, data["net"].sum(), data["profit"].sum())
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
(2448, 17) 3159140 1476130

Вопрос 1. Как шёл год

[ ]Упражнение 1Динамика по месяцам решено

Сохраните в by_month таблицу по месяцам — сгруппируйте data по столбцу month: net и profit — суммы, growth — рост net к прошлому месяцу (три знака). В best_month и worst_month сохраните номера лучшего и худшего месяца по чистой выручке.

by_month = ...
# добавьте в by_month столбец growth
best_month = ...
worst_month = ...

[ ]Месяцы
by_month
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
net profit growth
month
1 297120 140940 NaN
2 244070 116750 -0.179
3 288570 135260 0.182
4 322960 147230 0.119
5 248930 115490 -0.229
6 250030 114500 0.004
7 171250 79520 -0.315
8 206820 96430 0.208
9 242450 110940 0.172
10 247020 113210 0.019
11 278680 129850 0.128
12 361240 176010 0.296
Вывод появится, когда решите упражнение «Динамика по месяцам», — иначе он подскажет ответ. Ячейку можно и выполнить.

Вопрос 2. На чём зарабатываем

[ ]Упражнение 2Категории: прибыль, маржа, возвраты решено

Сохраните в by_category таблицу по категориям: net, profit — суммы; sold — продано штук (quantity); returned — возвращено штук; margin — прибыль, делённая на чистую выручку; return_rate — доля возвращённых штук. Доли — три знака. Отсортируйте по убыванию прибыли.

by_category = ...

[ ]Категории
by_category
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
net profit sold returned margin return_rate
category
Кофе 1830330 781430 2138 89 0.427 0.042
Чай 581140 325660 1598 69 0.560 0.043
Посуда 374350 187680 280 10 0.501 0.036
Сладости 212440 106260 1025 38 0.500 0.037
Аксессуары 160880 75100 169 8 0.467 0.047
Вывод появится, когда решите упражнение «Категории: прибыль, маржа, возвраты», — иначе он подскажет ответ. Ячейку можно и выполнить.

Вопрос 3. Где продаём

[ ]Упражнение 3Города и средний чек решено

Сохраните в by_city таблицу по городам: net — чистая выручка, orders — число разных заказов, buyers — число разных покупателей, check — средний чек (net на заказ, до рублей), share — доля города в общей чистой выручке (три знака). В top_check_city сохраните город с наибольшим средним чеком.

by_city = ...
top_check_city = ...

Вопрос 4. Что и где

[ ]Упражнение 4Категории × города решено

Сохраните в cross сводную таблицу чистой выручки: категории в строках, города в столбцах, с итогами «Всего». В moscow_coffee_share сохраните долю московского кофе во всей чистой выручке магазина — посчитайте её по ячейкам cross.

cross = ...
moscow_coffee_share = ...

[ ]Сводная
cross
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
city Екатеринбург Казань Москва Новосибирск Санкт-Петербург Всего
category
Аксессуары 28370 30940 51300 11050 39220 160880
Кофе 222050 247600 735480 172860 452340 1830330
Посуда 54500 48220 154550 39540 77540 374350
Сладости 29480 25350 82350 18040 57220 212440
Чай 75100 73390 221380 62060 149210 581140
Всего 409500 425500 1245060 303550 775530 3159140
Вывод появится, когда решите упражнение «Категории × города», — иначе он подскажет ответ. Ячейку можно и выполнить.

Вопрос 5. Кому продаём

[ ]Упражнение 5Сегменты и лучшие покупатели решено

Сохраните в by_segment таблицу по сегментам: net, buyers (число разных покупателей) и per_buyer — чистая выручка на покупателя, до рублей. В vip сохраните пять покупателей с наибольшей чистой выручкой: столбцы customer_id, city, segment, net, индекс с нуля.

by_segment = ...
vip = ...

Графики

[ ]Упражнение 6Год на одном графике решено

Постройте линейный график столбцов net и profit таблицы by_month с заголовком «Чистая выручка и прибыль по месяцам, 2025» и сохраните в ax. Подпишите оси: X — «месяц», Y — «₽».

ax = ...
# подпишите оси

[ ]Прибыль по категориям
by_category["profit"].sort_values().plot(kind="barh", title="Прибыль по категориям, ₽")
Выводсохранённый · нажмите «Выполнить», чтобы получить свойГрафик: Прибыль по категориям
Вывод появится, когда решите упражнение «Категории: прибыль, маржа, возвраты», — иначе он подскажет ответ. Ячейку можно и выполнить.

Отчёт

[ ]Главные числа
total_net = data["net"].sum()
total_profit = data["profit"].sum()
print("Выручка:", data["revenue"].sum(), "₽ · после возвратов:", total_net, "₽")
print("Прибыль:", total_profit, "₽ · маржа:", round(total_profit / total_net * 100, 1), "%")
print("Заказов:", data["order_id"].nunique(), "· покупателей:", data["customer_id"].nunique())
print("Лучший месяц:", best_month, "· худший:", worst_month)
print("Самый высокий средний чек:", top_check_city)
print(by_segment)
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
Выручка: 3301420 ₽ · после возвратов: 3159140 ₽
Прибыль: 1476130 ₽ · маржа: 46.7 %
Заказов: 1576 · покупателей: 213
Лучший месяц: 12 · худший: 7
Самый высокий средний чек: Санкт-Петербург
                net  buyers  per_buyer
segment
новый       1109020      86    12896.0
оптовый      737000      25    29480.0
постоянный  1313120     102    12874.0
Итог появится, когда решите все упражнения урока, — в нём ответы. Ячейку можно и выполнить.

Выводы

Год в целом. Магазин продал товаров на 3.30 млн ₽; после возвратов осталось 3.16 млн ₽, из них прибыль — 1.48 млн ₽, маржа 46.7 %. 1576 заказов от 213 покупателей.

Сезонность. Лучший месяц — декабрь (361 тыс. ₽, +30 % к ноябрю), худший — июль (171 тыс. ₽, −32 % к июню). Лето — провал, четвёртый квартал — пик. К летнему спаду стоит готовиться заранее: акциями или холодными напитками в ассортименте.

Категории. Больше половины прибыли даёт кофе, но маржа у него самая низкая — 43 %. Самая маржинальная категория — чай (56 %), и он же хорошо продаётся зимой. Возвращают 4 % проданных штук, и доля возвратов по категориям почти одинакова — проблемной категории нет.

Города. Москва — 39 % чистой выручки, Санкт-Петербург — четверть. Средний чек по городам отличается мало: от 1860 ₽ в Новосибирске до 2100 ₽ в Санкт-Петербурге.

Покупатели. 25 оптовых покупателей приносят почти четверть выручки: на каждого приходится 29 тыс. ₽ в год — в два с лишним раза больше, чем на обычного. Четверо из пяти лучших покупателей — оптовые. Потеря даже нескольких таких клиентов заметно ударит по выручке.

Выводы с ответами появятся, когда решите все упражнения урока.

Что вы теперь умеете

За курс вы прошли весь путь аналитика: загрузить данные, осмотреть, почистить, соединить, посчитать, свернуть, показать и объяснить. Этот отчёт — не учебное упражнение, а обычная рабочая задача, и вы решили её сами.

Дальше — практика на своих данных. Возьмите любую выгрузку, которая вам интересна, и задайте ей вопросы. Когда забудется название метода или параметра — справочник под рукой.

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

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

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

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