【问题标题】:Weighted average element-wise between two arrays两个数组之间的加权平均元素
【发布时间】:2021-11-11 18:40:00
【问题描述】:

我有两个数字数组,我想计算这些数组之间的加权平均元素并将其存储在一个新数组中。

我现在使用的解决方案是:

array_1 = [0,1,2,3,4]
array_2 = [2,3,4,5,6]

weight_1 = 0.5
weight_2 = 0.5

array_3 = np.zeros(array_1.shape)

for i in range(0, len(array_1)) : 
    array_3[i] = np.average(a=[array_1[i], array_2[i]], weights=[weight_1, weight_2])

print(array_3)
>> [1,2,3,4,5]

问题是它不是很有效。我怎样才能更有效地做到这一点?

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    只需使用 NumPy 的矢量化操作。为此,首先将列表转换为数组,然后将每个数组乘以各自的权重并求和

    import numpy as np
    
    array_1 = np.array([0,1,2,3,4])
    array_2 = np.array([2,3,4,5,6])
    
    weight_1 = 0.5
    weight_2 = 0.5
    
    array_3 = weight_1*array_1 + weight_2*array_2
    # array([1., 2., 3., 4., 5.])
    

    使用np.average 的直接 NumPy 解决方案如下,其中axis=0 表示逐行取平均(使用两列)。 np.vstack() 只是将两个数组垂直堆叠。

    np.average(np.vstack((array_1, array_2)), axis=0, weights=[weight_1, weight_2])
    

    正如@yatu 所指出的,您还可以传递数组列表并指定轴

    np.average([array_1, array_2], axis=0, weights=[weight_1, weight_2])
    

    受@yatu 回答中的 cmets 启发的时间比较:如您所见,列表理解和 zip 在这里稍微快一些,但这种性能适用于小型数组。我敢肯定,对于大型数组,矢量化解决方案将接管

    德维什的方法

    %timeit result = [ item1 * weight_1 + item2 * weight_2 for item1, item2 in zip(array_1, array_2)]
    # 25.5 µs ± 3.75 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
    

    %timeit np.average([array_1, array_2], axis=0, weights=[weight_1, weight_2])
    # 42.9 µs ± 2.94 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
    

    %timeit np.average(np.vstack((array_1, array_2)), axis=0, weights=[weight_1, weight_2])
    # 44.8 µs ± 4.98 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
    

    【讨论】:

      【解决方案2】:

      你可以zip两个迭代器,并将每个元素乘以对应的权重

      array_1 = [0,1,2,3,4]
      array_2 = [2,3,4,5,6]
      
      weight_1 = 0.5
      weight_2 = 0.5
      
      #Zip both iterators and multiply weight with corresponding item
      result = [ item1 * weight_1 + item2 * weight_2 for item1, item2 in zip(array_1, array_2)]
      print(result)
      

      输出将是

      [1.0, 2.0, 3.0, 4.0, 5.0]
      

      【讨论】:

        【解决方案3】:

        鉴于您使用的是 NumPy,您可以通过以下方式轻松对其进行矢量化:

        array_1 = np.array([0,1,2,3,4])
        array_2 = np.array([2,3,4,5,6])
        
        weight_1 = 0.5
        weight_2 = 0.5
        
        array_1*weight_1 + array_2*weight_2
        # array([1., 2., 3., 4., 5.])
        

        这可以推广到多个数组和权重吗?

        要获得更普遍的答案,最好的方法是使用np.average,它接受array_like 用于数组和weights,以应用于其中的每一个:

        np.average([array_1, array_2], weights=[weight_1, weight_2], axis=0)
        # array([1., 2., 3., 4., 5.])
        

        【讨论】:

        • 没有人提供zip 解决方案:)
        • 好吧,OP 确实说了一个更有效的解决方案。所以我们在这里寻找一个矢量化的@DeveshKumarSingh
        • 所以 numpy 向量化比压缩和列出 comp @yatu 更有效?
        • 是的,通常是这样,因为您将所有循环都放到c 级别@DeveshKumarSingh
        • @DeveshKumarSingh:检查我对计时性能的回答。您的方法确实在这里获胜但是我确信对于大型数组,矢量化解决方案将接管
        【解决方案4】:

        加权平均的方程不应该是:

        (array_1*weight_1 + array_2*weight_2)/(weight_1 + weighted_2)

        【讨论】:

        • 这似乎不是一个答案,但可能是一个相关的评论。请作为对该问题的评论发表。可选择链接到理论图像。
        • 我想发,但由于我的声誉低于 50,我无法将其发布为评论,我只能将其发布为答案
        猜你喜欢
        • 1970-01-01
        • 2020-04-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-23
        • 1970-01-01
        • 1970-01-01
        • 2014-04-17
        • 2017-06-12
        相关资源
        最近更新 更多