Weighted averaging a list

52,236

Solution 1

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

is the same as:

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

which is the same as:

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

which is the same as:

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

Result:

14.415602815646439

Solution 2

You could use numpy.average to calculate weighted 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

Solution 3

This looks like a weighted average.

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

This outputs 3.38, which indeed tends more toward the values with the highest weights.

Solution 4

Let's use python zip function

zip([iterable, ...])

This function returns a list of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables. The returned list is truncated in length to the length of the shortest argument sequence. When there are multiple arguments which are all of the same length, zip() is similar to map() with an initial argument of None. With a single sequence argument, it returns a list of 1-tuples. With no arguments, it returns an empty list.

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)
Share:
52,236
Rontron
Author by

Rontron

Updated on November 23, 2021

Comments

  • Rontron
    Rontron over 2 years

    Thanks for your responses. Yes, I was looking for the weighted average.

    rate = [14.424, 14.421, 14.417, 14.413, 14.41]
    
    amount = [3058.0, 8826.0, 56705.0, 30657.0, 12984.0]
    

    I want the weighted average of the top list based on each item of the bottom list.

    So, if the first bottom-list item is small (such as 3,058 compared to the total 112,230), then the first top-list item should have less of an effect on the top-list average.

    Here is some of what I have tried. It gives me an answer that looks right, but I am not sure if it follows what I am looking for.

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

    EDIT: After comparing other responses with my code, I decided to use the zip code to keep it as short as possible.