Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Average elements in sublists

Tags:

python

list

numpy

I have a list, created by an iterative process, composed of a variable number of sublists all of them with the same number of elements; which is also variable. For example, on one iteration I can have 4 sublists of 3 elements each, like so:

list_1 = [[1,3,5], [7,4,9], [3,6,2], [5,4,7]]

and in the next iteration of the code I can have:

list_2 = [[2,4,8,3,5], [2,4,9,1,3], [1,9,6,3,6]]

that is, 3 sublists of 5 elements each.

For a given iteration all sublist will always have the same number of elements.

I need a way to generate for iteration i a new list out of list_i, containing the average of all elements located in the same position in each sublist. So in the first case for list_1 I'd get:

avrg_list = [4.0, 4.25, 5.75]

and in the second case for list_2:

avrg_list = [1.67, 5.67, 7.67, 2.33, 4.67]

How can I do this with a flexible code that will adjust itself to different number of sublists and elements?

like image 706
Gabriel Avatar asked Jan 12 '23 12:01

Gabriel


2 Answers

are you interested in using numpy?

In [19]: list_1 = [[1,3,5], [7,4,9], [3,6,2], [5,4,7]]
In [22]: np.mean(list_1, 0)
Out[22]: array([ 4.  ,  4.25,  5.75])
like image 164
Hammer Avatar answered Jan 21 '23 09:01

Hammer


Use zip with *:

>>> [sum(x)/float(len(x)) for x in zip(*list_1)]
[4.0, 4.25, 5.75]
>>> [sum(x)/float(len(x)) for x in zip(*list_2)]
[1.6666666666666667, 5.666666666666667, 7.666666666666667, 2.3333333333333335, 4.666666666666667]

From docs:

zip() in conjunction with the * operator can be used to unzip a list.

>>> zip(*list_1)
[(1, 7, 3, 5), (3, 4, 6, 4), (5, 9, 2, 7)]

Timing comparisons:

>>> from itertools import izip
>>> import numpy as np
>>> lis = list_1*1000
>>> arr = np.array(lis)
>>> %timeit np.mean(lis, 0)
10 loops, best of 3: 31.9 ms per loop
>>> %timeit np.mean(arr, 0)
1000 loops, best of 3: 221 us per loop    #clear winner
>>> %timeit [sum(x)/float(len(x)) for x in zip(*lis)]
100 loops, best of 3: 826 us per loop
#itertools.izip is memory efficient.
>>> %timeit [sum(x)/float(len(x)) for x in izip(*lis)]
100 loops, best of 3: 881 us per loop
like image 22
Ashwini Chaudhary Avatar answered Jan 21 '23 10:01

Ashwini Chaudhary