How to find mean of an array which has two elements in Python?

Viewed 466

I need to find mean of an array which is like: [('a', 5), ('b', 2), ('a', 4), ('b', 6)]

Result should be like; [('a', 4.5), ('b', 4)]

5 Answers

You can put all your tuples in a defaultdict, using the first value to group them into a list and then calculate the mean:

from collections import defaultdict

d = defaultdict(list)

for key,value in [('a', 5), ('b', 2), ('a', 4), ('b', 6)]:
    d[key].append(value)

mean = []

for k,values in d.items():
    # mean.append((k,sum(values)/float(len(values)))) #python 2
    mean.append((k,sum(values)/len(values)))

print(mean) # [('a', 4.5), ('b', 4.0)]

You can collect the numbers with a collections.defaultdict(), then apply statistics.mean() on each group of numbers:

from statistics import mean
from collections import defaultdict

lst = [('a', 5), ('b', 2), ('a', 4), ('b', 6)]

d = defaultdict(list)
for k, v in lst:
    d[k].append(v)

means = [(k, mean(v)) for k, v in d.items()]

print(means)
# [('a', 4.5), ('b', 4)]

You can also use itertools.groupby() to group the tuples:

from statistics import mean
from itertools import groupby
from operator import itemgetter

lst = [("a", 5), ("b", 2), ("a", 4), ("b", 6)]

means = [
    (k, mean(map(itemgetter(1), g)))
    for k, g in groupby(sorted(lst, key=itemgetter(0)), key=itemgetter(0))
]

print(means)
[('a', 4.5), ('b', 4)]

We can use pandas for this:

import pandas as pd

pd.DataFrame(data).groupby(0)[1].mean().to_dict()

this will give us:

>>> pd.DataFrame(data).groupby(0)[1].mean().to_dict()
{'a': 4.5, 'b': 4.0}

or we can convert this to a list of 2-tuples with:

list(pd.DataFrame(data).groupby(0)[1].mean().to_dict().items())

which gives:

>>> list(pd.DataFrame(data).groupby(0)[1].mean().to_dict().items())
[('a', 4.5), ('b', 4.0)]

The above is thus more a "declarative" approach: we specify what we want, not much how we want to do this.

Raw solution without additional libraries could look like this:

def mean(l):
    result = {}
    for key, value in l:
        if key not in result:
            result[key] = []
        result[key].append(value)

    return [(k, sum(v)/len(v)) for k, v in result.items()]

lst = [('a', 5), ('b', 2), ('a', 4), ('b', 6)]
m = mean(lst)

print(m)
# [('a', 4.5), ('b', 4.0)]

If you wish, you can also try the below reusable code (without using any external libraries).

>>> def get_mean(l):
...     d = {}
...     for k, v in l:
...         if k in d:
...             d[k].append(v)
...         else:
...             d[k] = [v]
...     result = [(k, sum(d[k])/len(d[k])) for k in d]
...     return result
...
>>> l = [('a', 5), ('b', 2), ('a', 4), ('b', 6)]
>>> new_l = get_mean(l)
>>> new_l
[('a', 4.5), ('b', 4.0)]
>>>
Related