/
goliy_rez
/
Variant_2
Обзор
Документация
Войти
/
goliy_rez
/
Variant_2
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
program_report/app.py
171 строка
7 KB
goliy_rez
Create: .gitignore, app.py, requirements.txt
09 авг 2026, 21:13
Верифицирован
09 авг 2026, 21:13
1e8484e
Код
Авторство
О чём код?
import os from itertools import product import plotly.express as px import pandas as pd import matplotlib.pyplot as plt import streamlit as st # Вызов делается один раз на верхнем уровне приложения st.set_page_config(page_title="Project Report", layout="wide") tab1 , tab2 , tab3, tab4 , tab5= st.tabs(["Пробные расчет","Сырые данные", "Расчет метрик", "Визуализация", "Визуализация 2.0"]) with tab1: @st.cache_data(show_spinner="Загрузка файлов...") def load_all_data(): df_1 = pd.read_csv('data/items.csv') df_2 = pd.read_csv('data/orders.csv') df_3 = pd.read_csv('data/users.csv') return df_1, df_2, df_3 st.title("Отчет по пользователям") if not os.path.exists('data'): st.error("Папка 'data' не найдена. Проверьте структуру проекта.") else: df_items, df_orders, df_users = load_all_data() st.subheader("📦 Товары") st.dataframe(df_items, use_container_width=True) st.subheader("🛒 Заказы") st.dataframe(df_orders, use_container_width=True) st.subheader("👤 Пользователи") st.dataframe(df_users, use_container_width=True) orders_with_users = pd.merge(df_orders, df_users, on='user_id', how='left', suffixes=('', '_user') ) final_df = pd.merge(orders_with_users, df_items, on='item_id', how='left', suffixes=('', '_item')) final_df['revenue'] = final_df['quantity'] * final_df['price_per_unit'] # Удален второй блок формирования summary и повторного вывода заголовка summary = pd.DataFrame({ 'Тип данных': final_df.dtypes, 'Непустых значений': final_df.count(), 'Пропусков': final_df.isnull().sum() }) st.subheader("Структура итоговой таблицы") st.dataframe(summary) final_df['registration_date'] = pd.to_datetime(final_df['registration_date']) final_df['order_date'] = pd.to_datetime(final_df['order_date']) date_format = "%d.%m.%Y %H:%M" with tab2: st.subheader("СВОдная таблица") st.dataframe(final_df, use_container_width=True) with tab3: total_orders = final_df['order_id'].nunique() total_revenue = final_df['revenue'].sum() unique_users = final_df['user_id'].nunique() average_check = total_revenue / total_orders if total_orders > 0 else 0 col1, col2, col3, col4 = st.columns(4) col1.metric(label="Всего заказов", value=f"{total_orders:,}".replace(',', ' ')) col2.metric(label="Общая выручка", value=f"{total_revenue:,.2f} ₽".replace(',', ' ')) col3.metric(label="Уникальных клиентов", value=unique_users) col4.metric(label="Средний чек", value=f"{average_check:,.2f} ₽".replace(',', ' ')) with tab4: revenue_by_item = final_df.groupby('item_name')['revenue'].sum().sort_values(ascending=False) top_10_items = revenue_by_item.head(10) fig, ax = plt.subplots(figsize=(12, 7)) bars = ax.barh(top_10_items.index, top_10_items.values, color='skyblue', edgecolor='black', height=0.6) ax.invert_yaxis() ax.set_title('Топ-10 товаров по выручке', fontsize=16, fontweight='bold', pad=20) ax.set_xlabel('Общая выручка, ₽', fontsize=12, labelpad=10) ax.set_ylabel('Название товара', fontsize=12, labelpad=10) ax.xaxis.grid(True, linestyle='--', alpha=0.6) ax.set_axisbelow(True) for spine in ['top', 'right']: ax.spines[spine].set_visible(False) for i, v in enumerate(top_10_items.values): ax.text(v + max(top_10_items.values) * 0.01, i, f'{v:,.2f} ₽'.replace(',', ' '), va='center', fontsize=10, fontweight='bold') plt.tight_layout() st.subheader("📊 Аналитика продаж") st.pyplot(fig) product_sale = final_df.groupby('item_name')['quantity'].sum().reset_index() fix_pie = px.pie( product_sale, values='quantity', names='item_name', title='Структура продаж по количеству товаров' ) st.plotly_chart(fix_pie, width='stretch') if 'order_date' in final_df.columns and not pd.api.types.is_datetime64_any_dtype(final_df['order_date']): final_df['order_date'] = pd.to_datetime(final_df['order_date'], errors='coerce') fig_line = px.line( final_df, x='order_date', y='base_price', title='Динамика выручки по дням' ) st.plotly_chart(fig_line, width='stretch') with tab5: st.header("📊 Аналитика продаж") # 2. ВЫРУЧКА ПО КАТЕГОРИЯМ (PLOTLY PIE) st.subheader("Доля категорий в общей выручке") revenue_by_category = final_df.groupby('category')['revenue'].sum() fig2 = px.pie( values=revenue_by_category.values, names=revenue_by_category.index, title='Распределение выручки по категориям', hole=0.3 # Эффект "пончика" ) fig2.update_traces(textposition='inside', textinfo='percent+label', pull=[0.05 if i==0 else 0 for i in range(len(revenue_by_category))]) st.plotly_chart(fig2, use_container_width=True) st.markdown("***") # Разделитель # 3. ЗАВИСИМОСТЬ ОТ ДНЯ НЕДЕЛИ (PLOTLY BAR) st.subheader("Количество заказов по дням недели") final_df['order_date'] = pd.to_datetime(final_df['order_date']) final_df['day_of_week'] = final_df['order_date'].dt.day_name() # Сортируем дни недели правильно (Пн-Вс), а не по алфавиту days_order = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] orders_by_day = final_df.groupby('day_of_week')['order_id'].count().reindex(days_order) fig3 = px.bar( x=orders_by_day.index, y=orders_by_day.values, title='Заказы по дням недели', labels={'x': 'День недели', 'y': 'Кол-во заказов'}, text=orders_by_day.values, color_discrete_sequence=['cornflowerblue'] ) fig3.update_traces(textposition='outside') fig3.update_layout(xaxis={'categoryorder':'array', 'categoryarray':days_order}) st.plotly_chart(fig3, use_container_width=True)