加权平均列表

32
感谢您的回复。是的,我正在寻找加权平均数。
rate = [14.424, 14.421, 14.417, 14.413, 14.41]

amount = [3058.0, 8826.0, 56705.0, 30657.0, 12984.0]

我想要基于底部列表的每个项目计算出前若干个项目的加权平均值。

因此,如果第一个底部列表项目很小(例如3,058与总数112,230相比),则第一个顶部列表项目对顶部列表平均值的影响应该较小。

这是我尝试过的一些方法。它给了我一个看起来正确的答案,但我不确定它是否符合我的要求。

for g in range(len(rate)):
    rate[g] = rate[g] * (amount[g] / sum(amount))
rate = sum(rate)

编辑: 在与其他答案比较我的代码后,我决定使用邮政编码,以使其尽可能简短。


3
你是说加权平均? - user648852
@Pyson 这些列表中似乎没有一个总和为100%,所以我对此不确定。 - Malik Brahimi
如果你正在寻找加权平均值,就像@Pyson提到的那样,一个好主意是将第二个向量归一化,然后应用w.a算法。 - srj
我知道加权平均,只是脑子一抽。谢谢。 - Rontron
5个回答

54

你可以使用 numpy.average 来计算加权平均值。

In [13]: import numpy as np

In [14]: rate = [14.424, 14.421, 14.417, 14.413, 14.41]

In [15]: amount = [3058.0, 8826.0, 56705.0, 30657.0, 12984.0]

In [17]: weighted_avg = np.average(rate, weights=amount)

In [19]: weighted_avg
Out[19]: 14.415602815646439

1
谢谢,但我正在尝试使用包含的2.7.9库。 - Rontron
2
Numpy是事实上的标准库。 - Mayou36
1
de facto 是主观的。Numpy 不是标准库。 - John Scolaro

28
for g in range(len(rate)):
   rate[g] = rate[g] * amount[g] / sum(amount)
rate = sum(rate)

等同于:

sum(rate[g] * amount[g] / sum(amount) for g in range(len(rate)))

这与以下内容相同:

sum(rate[g] * amount[g] for g in range(len(rate))) / sum(amount)

即:

sum(x * y for x, y in zip(rate, amount)) / sum(amount)

结果为:

14.415602815646439

谢谢,这个有效。不过黄色高亮的那个给了我一个语法错误。 - Rontron
我再试了一遍,这次成功了。我可能不小心复制了页面上的额外内容。我将使用你您黄色标记的代码。谢谢! - Rontron
我强烈反对这个答案,而支持其他提出的np.average:numpy已经成为事实上的标准库。如果我们已经有了一个实现,就不要重新发明轮子(更不用说速度了)。 - Mayou36

9
这看起来像是加权平均数。
values = [1, 2, 3, 4, 5]
weights = [2, 8, 50, 30, 10]

s = 0
for x, y in zip(values, weights):
    s += x * y

average = s / sum(weights)
print(average) # 3.38

这将输出3.38,这确实更倾向于具有最高权重值的值。

2

让我们使用Python的zip函数。

zip([iterable, ...])

该函数返回一个元组列表,第 i 个元组包含每个参数序列或可迭代对象的第 i 个元素。返回的列表长度被截短为最短参数序列的长度。当有多个参数且它们的长度都相同时,zip() 类似于带有初始参数 None 的 map() 函数。如果只有一个序列参数,则返回一个包含 1 个元组的列表。如果没有参数,则返回一个空列表。
weights = [14.424, 14.421, 14.417, 14.413, 14.41]
values = [3058.0, 8826.0, 56705.0, 30657.0, 12984.0]
weighted_average = sum(weight * value for weight, value in zip(weights, values)) / sum(weights)

1
你把权重和价值搞反了。我希望基于千位数的权重来计算14,000个值的权重。 - Rontron

0
作为一个经过文档化和测试的函数:
def weighted_average(values, weights=None):
    """
    Returns the weighted average of `values` with weights `weights`
    Returns the simple aritmhmetic average if `weights` is None.
    >>> weighted_average([3, 9], [1, 2])
    7.0
    >>> 7 == (3*1 + 9*2) / (1 + 2)
    True
    """
    if weights == None:
        weights = [1 for _ in range(len(values))]
    normalization = 0
    val = 0
    for value, weight in zip(values, weights):
        val += value * weight
        normalization += weight
    return val / normalization

为了完整起见,这里提供另一种版本,其中值和权重存储在元组中:

def weighted_average(values_and_weights):
    """
    The input is expected in the form:
        [(value_1, weight_1), (value_2, weight_2), ...(value_n, weight_n)]
    >>> weighted_average([(3,1), (9,2)])
    7.0
    >>> 7 == (3*1 + 9*2) / (1 + 2)
    True

    """
    normalization = 0
    val = 0
    for value, weight in values_and_weights:
        val += value * weight
        normalization += weight
    return val / normalization

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接