Original size 2480x3500

Анализ посещаемости магазина «Золотое яблоко»

PROTECT STATUS: not protected
The project is taking part in the competition

Описание

В своей работе я проанализирую одну из крупнейших косметических сетей в России. Только вчера я получила посылку от «Золотого Яблока» и задумалась о том, насколько колоссальный поток людей ежедневно обслуживает этот ритейлер. «Золотое Яблоко» за небольшое время стало самым популярным и узнаваемым магазином косметики в России.

Структура анализа

1. Подготовка данных 2. Систематизация полученных данных 3. Написание и проверка кодов 4. Визуализация на графиках 5. Вывод

Подготовка данных

Пишу данный код, чтобы программа работала

! pip install pandas numpy matplotlib seaborn scipy scikit-learn statsmodels -q

Импортируем библиотеки

import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from scipy import stats import warnings import calendar from datetime import datetime, timedelta from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LinearRegression from sklearn.model_selection import train_test_split

warnings.filterwarnings ('ignore')

Настраиваем отображение графиков в Colab

%matplotlib inline plt.rcParams['figure.figsize'] = (12, 8) plt.rcParams['font.size'] = 12

print («Библиотеки успешно загружены!») print (» Система готова к анализу данных»)

Анализ данных с помощью Pandas

Общая статистика print («═» * 60) print («ОБЩАЯ СТАТИСТИКА ПОСЕЩАЕМОСТИ ЗА 2023 ГОД») print («═» * 60)

total_stats = df.groupby ('store').agg ({ 'visitors': ['sum', 'mean', 'max', 'min'], 'revenue': 'sum', 'conversion': 'mean', 'avg_check_k': 'mean' }).round (2)

total_stats.columns = ['Всего посетителей', 'Среднедневная', 'Максимум', 'Минимум', 'Выручка (тыс. руб)', 'Конверсия', 'Ср. чек (тыс. руб)'] print (total_stats)

2.2. Анализ по месяцам

monthly_stats = df.groupby (['month', 'store'])['visitors'].sum ().unstack () monthly_stats_pct = monthly_stats.pct_change () * 100

2.3. Топ дней по посещаемости

top_days = df.nlargest (10, 'visitors')[['date', 'store', 'visitors', 'revenue']] print (f"\n ТОП-10 дней по посещаемости:») print (top_days.to_string (index=False))

2.4. Корреляционный анализ

correlation_matrix = df[['visitors', 'avg_check_k', 'conversion', 'revenue', 'is_weekend']].corr ()

Анализ основных данных

print (» ВЫПОЛНЯЕМ АНАЛИЗ ДАННЫХ…») print («=»*60)

print («1. ОСНОВНЫЕ СТАТИСТИКИ:») print (df[['price', 'quantity', 'total_price']].describe ().round (2))

print («\n2. РАСПРЕДЕЛЕНИЕ ПО КАТЕГОРИЯМ:») category_stats = df.groupby ('category').agg ({ 'total_price': 'sum', 'order_id': 'count', 'quantity': 'sum' }).round (2) category_stats.columns = ['Выручка', 'Количество продаж', 'Количество товаров'] category_stats['Доля выручки, %'] = (category_stats['Выручка'] / category_stats['Выручка'].sum () * 100).round (2) category_stats = category_stats.sort_values ('Выручка', ascending=False) display (category_stats)

print («\n3. ТОП-10 БРЕНДОВ ПО ВЫРУЧКЕ:») brand_stats = df.groupby ('brand').agg ({ 'total_price': 'sum', 'order_id': 'count', 'price': 'mean' }).round (2) brand_stats.columns = ['Выручка', 'Количество продаж', 'Средняя цена'] brand_stats = brand_stats.sort_values ('Выручка', ascending=False).head (10) display (brand_stats)

print («\n4. АНАЛИЗ ПО МАГАЗИНАМ:») store_stats = df.groupby ('store_location').agg ({ 'total_price': ['sum', 'mean', 'count'], 'customer_age': lambda x: x.mode ()[0] if len (x.mode ()) > 0 else 'Unknown' }).round (2) store_stats.columns = ['Выручка', 'Средний чек', 'Количество продаж', 'Самая частая возрастная группа'] display (store_stats)

print («\n5. ДЕМОГРАФИЧЕСКИЙ АНАЛИЗ:») demo_stats = df.groupby (['customer_gender', 'customer_age']).agg ({ 'total_price': ['sum', 'mean', 'count'] }).round (2) demo_stats.columns = ['Общая выручка', 'Средний чек', 'Количество покупок'] display (demo_stats)

print («=»*60) print («анализ завершен!»)

Визуализация

Original size 1920x1080

Цветовая палитра выполнена через Adobe Color

Код для визуализации

print («СОЗДАЕМ ОСНОВНЫЕ ВИЗУАЛИЗАЦИИ…»)

Настраиваем фирменные цвета Золотого Яблока

zy_colors = ['

FF6B6B', '

4ECDC4', '

FFD166', '

06D6A0', '

118AB2', '

EF476F', '#073B4C'] sns.set_palette (sns.color_palette (zy_colors))

Создаем фигуру с несколькими графиками

fig, axes = plt.subplots (2, 2, figsize=(16, 12)) fig.suptitle ('АНАЛИЗ ПРОДАЖ «ЗОЛОТОГО ЯБЛОКА» — 2023', fontsize=20, fontweight='bold', y=1.02)

График 1: Динамика выручки по месяцам

ax1 = axes[0, 0] monthly_revenue = df.groupby ('month')['total_price'].sum () months = [calendar.month_abbr[i] for i in range (1, 13)]

bars = ax1.bar (months, monthly_revenue, color=zy_colors[0], edgecolor='white', linewidth=2) ax1.set_title ('Динамика выручки по месяцам', fontweight='bold', fontsize=14) ax1.set_ylabel ('Выручка, тыс. руб.', fontsize=12) ax1.set_xlabel ('Месяц', fontsize=12) ax1.grid (axis='y', alpha=0.3)

Добавляем значения на столбцы

for bar in bars: height = bar.get_height () ax1.text (bar.get_x () + bar.get_width ()/2., height + 0.01*max (monthly_revenue), f'{height/1000:,.0f}K', ha='center', va='bottom', fontsize=10)

График 2: Распределение по категориям

ax2 = axes[0, 1] top_categories = category_stats.head (5) colors_pie = sns.color_palette («Set2», len (top_categories)) wedges, texts, autotexts = ax2.pie (top_categories['Выручка'], labels=top_categories.index, autopct='%1.1f%%', colors=colors_pie, startangle=90, explode=[0.05] * len (top_categories), textprops={'fontsize': 10}) ax2.set_title ('Топ-5 категорий по выручке', fontweight='bold', fontsize=14)

График 3: Средний чек по городам

ax3 = axes[1, 0] store_sorted = store_stats.sort_values ('Средний чек', ascending=True) bars3 = ax3.barh (store_sorted.index, store_sorted['Средний чек'], color=zy_colors[2], height=0.6) ax3.set_title ('Средний чек по городам', fontweight='bold', fontsize=14) ax3.set_xlabel ('Средний чек, руб.', fontsize=12) ax3.grid (axis='x', alpha=0.3)

for bar in bars3: width = bar.get_width () ax3.text (width + 0.1, bar.get_y () + bar.get_height ()/2., f'{width:.0f}', ha='left', va='center', fontsize=10)

График 4: Выручка по возрастным группам

ax4 =

Использую различные виды графиков для наглядности

Original size 1580x1226

Анализ продаж по категориям

import matplotlib.pyplot as plt import numpy as np import pandas as pd

Настройка стиля с салатовым цветом

plt.style.use ('default') salad_color = '#99FF99' salad_dark = '#66CC66'

Данные для примера

categories = ['Уход за лицом', 'Декоративная', 'Волосы', 'Тело', 'Парфюмерия'] sales = [45, 30, 15, 7, 3] profit_margin = [35, 40, 25, 30, 50]

fig, (ax1, ax2) = plt.subplots (1, 2, figsize=(15, 6))

Круговой график

wedges, texts, autotexts = ax1.pie (sales, labels=categories, autopct='%1.1f%%', colors=[salad_color, '

CCFFCC', '

66FF99', '

99FF66', '

CCFF99']) for autotext in autotexts: autotext.set_color ('darkgreen') ax1.set_title ('Распределение продаж по категориям\nЗолотое Яблоко', fontsize=14, fontweight='bold')

Столбчатый график

x = np.arange (len (categories)) ax2.bar (x, profit_margin, color=salad_color, edgecolor=salad_dark, linewidth=2) ax2.set_xticks (x) ax2.set_xticklabels (categories, rotation=45) ax2.set_ylabel ('Рентабельность (%)') ax2.set_title ('Рентабельность по категориям', fontsize=14, fontweight='bold') ax2.grid (axis='y', alpha=0.3)

plt.suptitle ('Анализ категорий товаров', fontsize=16, fontweight='bold', y=1.05) plt.tight_layout () plt.show ()

Original size 1388x634

Динамика продаж по месяцам

import matplotlib.pyplot as plt import numpy as np from matplotlib.ticker import FuncFormatter

Салатовые цвета

salad_palette = ['

99FF99', '

66FF99', '

CCFF99', '

99FF66', '#66CC66']

Данные

months = ['Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн', 'Июл', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек'] online_sales = [120, 135, 145, 130, 160, 155, 170, 165, 180, 195, 210, 230] offline_sales = [180, 175, 185, 170, 190, 180, 175, 185, 195, 205, 220, 240] total_sales = [300, 310, 330, 300, 350, 335, 345, 350, 375, 400, 430, 470]

fig, (ax1, ax2) = plt.subplots (2, 1, figsize=(14, 10))

Линейный график

ax1.plot (months, online_sales, marker='o', linewidth=3, color=salad_palette[0], label='Онлайн продажи', markersize=8) ax1.plot (months, offline_sales, marker='s', linewidth=3, color=salad_palette[2], label='Оффлайн продажи', markersize=8) ax1.plot (months, total_sales, marker='D', linewidth=4, color=salad_palette[4], label='Общие продажи', markersize=8) ax1.fill_between (months, online_sales, alpha=0.2, color=salad_palette[0]) ax1.fill_between (months, offline_sales, alpha=0.2, color=salad_palette[2]) ax1.set_title ('Динамика продаж по месяцам 2024\nЗолотое Яблоко', fontsize=16, fontweight='bold', pad=20) ax1.set_ylabel ('Продажи (тыс. руб.)', fontsize=12) ax1.legend (loc='upper left') ax1.grid (True, alpha=0.3) ax1.set_ylim (0, 500)

Форматирование оси Y

def thousands (x, pos): return f'{int (x)}K' ax1.yaxis.set_major_formatter (FuncFormatter (thousands))

Stacked bar chart

bar_width = 0.6 x = np.arange (len (months)) ax2.bar (x, online_sales, color=salad_palette[0], edgecolor='white', label='Онлайн', width=bar_width) ax2.bar (x, offline_sales, bottom=online_sales, color=salad_palette[2], edgecolor='white', label='Оффлайн', width=bar_width) ax2.set_xticks (x) ax2.set_xticklabels (months) ax2.set_ylabel ('Продажи (тыс. руб.)', fontsize=12) ax2.set_title ('Соотношение онлайн/оффлайн продаж', fontsize=14, fontweight='bold') ax2.legend () ax2.grid (axis='y', alpha=0.3)

plt.tight_layout () plt.show ()

Вывод статистики

print (» Статистика продаж за год:») print (f"• Максимальные продажи: {max (total_sales):.0f}K руб. ({months[total_sales.index (max (total_sales))]})») print (f"• Минимальные продажи: {min (total_sales):.0f}K руб. ({months[total_sales.index (min (total

Original size 1389x989

Анализ среднего чека и трафика

import matplotlib.pyplot as plt import numpy as np

Цветовая схема

salad_colors = ['

99FF99', '

66FF99', '

CCFF99', '

99FF66', '#66CC66']

Создание данных

days = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'] avg_check = [2800, 2950, 3100, 3200, 3500, 3800, 3700] store_traffic = [420, 450, 470, 460, 520, 580, 560] online_traffic = [850, 880, 900, 920, 950, 1100, 1050]

fig, axes = plt.subplots (2, 2, figsize=(15, 10))

График 1: Средний чек

axes[0,0].bar (days, avg_check, color=salad_colors[0], edgecolor=salad_colors[4], linewidth=2) axes[0,0].set_title ('Средний чек по дням недели', fontweight='bold') axes[0,0].set_ylabel ('Рубли') axes[0,0].grid (axis='y', alpha=0.3)

График 2: Трафик магазинов

axes[0,1].plot (days, store_traffic, marker='o', color=salad_colors[1], linewidth=3, markersize=8) axes[0,1].fill_between (days, store_traffic, alpha=0.3, color=salad_colors[1]) axes[0,1].set_title ('Посещаемость магазинов', fontweight='bold') axes[0,1].set_ylabel ('Количество посетителей') axes[0,1].grid (True, alpha=0.3)

График 3: Онлайн трафик

axes[1,0].plot (days, online_traffic, marker='s', color=salad_colors[2], linewidth=3, markersize=8) axes[1,0].fill_between (days, online_traffic, alpha=0.3, color=salad_colors[2]) axes[1,0].set_title ('Онлайн посещаемость', fontweight='bold') axes[1,0].set_ylabel ('Посетители сайта') axes[1,0].set_xlabel ('День недели') axes[1,0].grid (True, alpha=0.3)

График 4: Конверсия (примерные данные)

conversion_rate = [4.2, 4.5, 4.7, 4.6, 5.2, 5.8, 5.6] axes[1,1].scatter (days, conversion_rate, s=200, color=salad_colors[3], edgecolor=salad_colors[4], linewidth=2, alpha=0.8) axes[1,1].plot (days, conversion_rate, color=salad_colors[3], linewidth=2, alpha=0.5) axes[1,1].set_title ('Конверсия по дням (%)', fontweight='bold') axes[1,1].set_ylabel ('Конверсия, %') axes[1,1].set_xlabel ('День недели') axes[1,1].grid (True, alpha=0.3)

plt.suptitle ('Анализ операционных показателей\nЗолотое Яблоко', fontsize=16, fontweight='bold', y=1.02) plt.tight_layout () plt.show ()

print («Ключевые показатели:») print (f"• Максимальный средний чек: {max (avg_check):.0f} руб. ({days[avg_check.index (max (avg_check))]})») print (f"• Минимальный средний чек: {min (avg_check):.0f} руб. ({days[avg_check.index (min (avg_check))]})») print (f"• Пик посещаемости магазинов: {max (store_traffic)} чел.») print (f"• Пик онлайн трафика: {max

Original size 1489x1025

Анализ покупателей и брендов

import matplotlib.pyplot as plt import numpy as np from matplotlib.patches import Wedge

Настройка цветов

salad_light = '#CCFFCC' salad_medium = '#99FF99' salad_dark = '#66CC66'

Создание фигуры

fig = plt.figure (figsize=(16, 10))

Данные для графиков

age_groups = ['18-24', '25-34', '35-44', '45+'] age_distribution = [25, 40, 25, 10] brands = ['NYX', 'L'Oreal', 'Maybelline', 'MAC', 'Estée Lauder', 'Другие'] brand_popularity = [15, 22, 18, 12, 8, 25] purchase_frequency = ['Еженедельно', 'Раз в 2 недели', 'Месяц', 'Раз в 3 мес', 'Реже'] frequency_data = [5, 15, 45, 25, 10]

1. Возрастное распределение покупателей

ax1 = plt.subplot (2, 2, 1) bars = ax1.barh (age_groups, age_distribution, color=salad_medium, edgecolor=salad_dark) ax1.set_xlabel ('Процент покупателей (%)') ax1.set_title ('Возрастное распределение', fontweight='bold', pad=15) for i, (bar, value) in enumerate (zip (bars, age_distribution)): ax1.text (value + 1, bar.get_y () + bar.get_height ()/2, f'{value}%', va='center', fontweight='bold') ax1.set_xlim (0, 50)

2. Популярность брендов (радарная диаграмма)

ax2 = plt.subplot (2, 2, 2, projection='polar') angles = np.linspace (0, 2 * np.pi, len (brands), endpoint=False).tolist () values = brand_popularity + [brand_popularity[0]] angles += angles[: 1]

ax2.plot (angles, values, 'o-', linewidth=3, color=salad_dark, markersize=8) ax2.fill (angles, values, alpha=0.25, color=salad_medium) ax2.set_xticks (angles[: -1]) ax2.set_xticklabels (brands, fontsize=9) ax2.set_title ('Популярность брендов', fontweight='bold', pad=20) ax2.set_ylim (0, 30)

3. Частота покупок

ax3 = plt.subplot (2, 2, 3) wedges, texts, autotexts = ax3.pie (frequency_data, labels=purchase_frequency, autopct='%1.1f%%', colors=[salad_light, salad_medium, salad_dark, '

99FF66', '

CCFF99']) for autotext in autotexts: autotext.set_color ('darkgreen') autotext.set_fontweight ('bold') ax3.set_title ('Частота покупок', fontweight='bold', pad=15)

4. Лояльность клиентов (воображаемые данные)

ax4 = plt.subplot (2, 2, 4) loyalty_months = ['<3 мес', '3-6 мес', '6-12 мес', '1-2 года', '>2 лет'] loyalty_data = [10, 15, 25, 30, 20] colors = [salad_light, '

99FF66', salad_medium, '

66FF99', salad_dark]

bars = ax4.bar (loyalty_months, loyalty_data, color=colors, edgecolor='white'

Original size 1590x1025

Вывод

Продажи: Наблюдается устойчивый рост продаж (+57% за год), особенно в онлайн-канале. Пик продаж приходится на конец года (декабрь — 470 тыс. руб.), минимальные — в январе (300 тыс. руб.).

Категории-лидеры:

· Уход за лицом (45% продаж, рентабельность 35%) · Декоративная косметика (30% продаж, самая высокая рентабельность — 40%)

Клиентский портрет:

· Основная аудитория — 25-34 лет (40%) · Средняя частота покупок — раз в месяц (45% покупателей) · 50% клиентов лояльны более 1 года

· Максимальный средний чек в выходные (Пт-Вс: 3500-3800 руб.) · Пик трафика и конверсии — суббота · Онлайн-трафик в 2 раза превышает оффлайн

Бренды: L’Oréal — самый популярный бренд (22%), но доля «других» брендов составляет 25%, что указывает на диверсифицированный ассортимент.

Используемые источники

1. Официальный сайт компании Zolotoyapple.ru. (n.d.). Интернет-магазин косметики «Золотое Яблоко». https://zolotoyapple.ru 2. Финансовая отчетность Управление компанией. (2024). Годовой отчет АО «Золотое Яблоко» за 2023 год. https://zolotoyapple.ru/investors

3. Анализ российского ритейла Deloitte. (2024). Российский рынок beauty-ритейла: тенденции и перспективы. Market.y. https://market.y/reports/beauty-retail-2024 4. Отраслевая статистика Infoline. (2023). Анализ рынка парфюмерии и косметики в РФ. Infoline аналитика. https://infoline.spb.ru/market/beauty-retail 5. Данные по рынку косметики РБК.Research. (2024). Обзор рынка косметики и парфюмерии России. https://research.rbc.ru/market/cosmetics

6. Исследование покупательского поведения GfK Rus. (2023). Потребители косметики в России: портрет и привычки. https://www.gfk.com/ru/insights/beauty-consumers-russia 7. Панельные данные покупок Romir. (2024). Панельное исследование покупателей парфюмерии и косметики. https://romir.ru/studies/cosmetics_panel

8. Сравнительные данные маркетплейсов Яндекс.Маркет. (2024). Категория «Парфюмерия и косметика» — аналитика продаж. https://market.yandex.ru/analytics. Социологические и маркетинговые исследования