网格搜索多参数广播:批量计算多权重组合的numpy加权平均值
实现方案
分两种常见场景给出numpy向量化实现,无需写Python层循环,运行效率远高于逐组遍历调用np.average的写法。
场景1:weights_true 每行是一组完整权重
即weights_true的结构是多组和你原单组weights结构一致的权重列表,每组长度和数组元素个数匹配,需要逐组计算加权平均。
import numpy as np # 定义输入数据 list_of_arrays = np.array([[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]]) weights_true = np.array([[1, 2, 3, 4], [5, 10, 15, 20], [50, 100, 150, 200], [5, 10, 15, 20]]) # 广播批量计算加权平均 # 权重扩展维度为(n_weights, 1, 元素数),和形状为(数组数, 元素数)的原数组自动广播 weighted_sum = (list_of_arrays * weights_true[:, None, :]).sum(axis=-1) weight_total = weights_true.sum(axis=-1)[:, None] results = weighted_sum / weight_total
你给出的示例中weights_true共4组权重,返回的results形状为(4, 3),每一行对应一组权重下3个数组的加权平均值。
可以用你之前的单组权重验证正确性:
test_w = np.array([[1, 20, 100, 10]]) test_res = (list_of_arrays * test_w[:, None, :]).sum(axis=-1) / test_w.sum(axis=-1)[:, None] print(test_res) # 输出 [[2.90839695 3.90839695 4.90839695]] 和你之前得到的结果完全一致
场景2:weights_true 每个子列表是对应位置的可选权重,需要计算所有组合
即weights_true第i个子列表存的是数组第i个位置的所有可选权重值,需要从每个位置选一个值拼成完整权重,遍历所有可能的拼法计算结果。
先生成所有权重组合的笛卡尔积,再复用上面的批量计算逻辑即可:
# 生成所有位置权重的笛卡尔积,展开为(n种组合, 元素数)的形状 mesh = np.meshgrid(*weights_true, indexing='ij') all_weight_combs = np.stack(mesh, axis=-1).reshape(-1, list_of_arrays.shape[1]) # 复用批量计算逻辑 weighted_sum = (list_of_arrays * all_weight_combs[:, None, :]).sum(axis=-1) weight_total = all_weight_combs.sum(axis=-1)[:, None] results = weighted_sum / weight_total
你给出的示例中每个位置有4个可选权重,总共有4^4=256种权重组合,返回的results形状为(256, 3),每一行对应一种权重组合下3个数组的加权平均值。
内容的提问来源于stack exchange,提问作者Denver Dang
相关产品推荐
相关产品推荐

