Загрузка данных


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)