snicksnackpaddywhack91
snicksnackpaddywhack91

Reputation: 159

Running Average using nested arrays and for-loops in Python without numpy

I'm trying to find a way to get a final running average of elements in a nested list using a for loop and I'm getting stuck on how to go about it. I have some sample data below, where the element[0] of each sublist is an id marker to be grouped, element[1] is the value to be summed, and element[2] is acting as a counter

listA = [[u001,4,1],[u002,6,1],[u003,3,1],[u001,12,1],[u002,1,1]
listB = []

for data in listA:
    if data[0] not in listB:
        listB.append(data)
    else: # essentailly if the value is in listB then do:
        listB[1] += data[1] #but this won't work because listB[1] is a list, and data[1] is a value
                  # i need to find a way to append the value data in listB WHERE listB[0] == data[0]
        AND
        listB[2] += 1 #at that specific location

eg pf each for loop pass:

listA:[[u001,4,1],[u002,6,1],[u003,3,1],[u001,12,1],[u002,1,1]
listB:[]
listB:[[u001,4,1]]
listB:[[u001,4,1],[u002,6,1]]
listB:[[u001,4,1],[u002,6,1],[u003,3,1]]
listB:[[u001,16,2],[u002,6,1],[u003,3,1]]
listB:[[u001,16,2],[u002,7,2],[u003,3,1]] #final desired result

Upvotes: 0

Views: 79

Answers (3)

MaPy
MaPy

Reputation: 505

Another solution using the itertools.groupby:

from operator import itemgetter
from itertools import groupby
listA = [['u001', 4, 1], ['u002', 6, 1],
         ['u003', 3, 1], ['u001', 12, 1],
         ['u002', 1, 1]]
listA.sort(key=itemgetter(0))
listB = []
for k, g in groupby(listA, key=itemgetter(0)):
    suma = 0
    counta = 0
    for x, y, z in g:
        suma += y
        counta += 1
    listB.append([x, suma, counta])

Upvotes: 1

Aeglas
Aeglas

Reputation: 196

The problem of the solution I'm posting is that has O(n²) time complexity. If you know that your data is not so big it could be good to use.

listA = [['u001',4,1],['u002',6,1],['u003',3,1],['u001',12,1],['u002',1,1]]
listB = []

for data in listA:
    found = False

    for elem in listB:
        if elem[0] == data[0]:
            elem[2] += 1
            elem[1] += data[1]
            found = True
            break

    if not found:
        listB.append(data)

Upvotes: 1

python_ged
python_ged

Reputation: 610

If you are willing to work with a dictionary, you can do it this way:

listA = [['u001',4,1],['u002',6,1],['u003',3,1],['u001',12,1],['u002',1,1]]
listB = {}

for a in listA:
    listB[a[0]] = [listB.get(a[0],[0,0])[0] + a[1],listB.get(a[0],[0,0])[1] + a[2]]

Upvotes: 2

Related Questions