import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# Убедимся, что переменные определены
date_col = 'end_month_plan'
target = 'renewed_fact_rate'
weight_col = 'portfolio_share'
# Функция агрегации (если ещё не определена)
def aggregate_weighted(df, group_col, value_col, weight_col):
return (df.groupby(group_col)
.apply(lambda g: pd.Series({
value_col: np.average(g[value_col], weights=g[weight_col]),
weight_col: g[weight_col].sum()
}))
.reset_index()
.sort_values(group_col))
# Список сегментов, для которых строим графики
segments = ['prem', 'mid']
# Создаём фигуру с двумя подграфиками
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
fig.suptitle('Сравнение фактической и прогнозной доли пролонгаций по сегментам', fontsize=14)
for idx, seg in enumerate(segments):
# Фильтруем данные по сегменту
df_seg = df[df['segment'] == seg].copy()
# Агрегируем факт и прогноз
fact_seg = aggregate_weighted(df_seg, date_col, target, weight_col)
pred_seg = aggregate_weighted(df_seg, date_col, 'prediction', weight_col)
# Объединяем для построения
comp_seg = fact_seg.merge(pred_seg, on=date_col, suffixes=('_fact', '_pred'))
# Строим график
axes[idx].plot(comp_seg[date_col], comp_seg[target], marker='o', label='Факт')
axes[idx].plot(comp_seg[date_col], comp_seg['prediction'], marker='x', label='Прогноз')
axes[idx].set_title(f'Сегмент {seg.upper()}')
axes[idx].legend()
axes[idx].grid(True)
axes[idx].tick_params(axis='x', rotation=45)
plt.tight_layout()
plt.show()