def aggregate_weighted(df, group_col, value_col, weight_col):
"""
Взвешенное среднее через группировку и агрегацию (без apply).
"""
# Суммируем произведения значения на вес
df_temp = df.copy()
df_temp['_weighted_sum'] = df_temp[value_col] * df_temp[weight_col]
agg = df_temp.groupby(group_col).agg({
'_weighted_sum': 'sum',
weight_col: 'sum'
}).reset_index()
agg[value_col] = agg['_weighted_sum'] / agg[weight_col]
agg = agg.drop(columns=['_weighted_sum'])
return agg.sort_values(group_col)