How to aggregate distinct values of one key then sum the matching values of the other key?

Issue

I’ve made a loop that gives me data in the following format:

name_quant = [{'name_id': 'S00004', 'quantity': '1'}, {'name_id': 'S00004', 'quantity': '2'}, {'name_id': 'S00003', 'quantity': '1'}, 
 {'name_id': 'S00003', 'quantity': '2'}, {'name_id': 'S00003', 'quantity': '2'}, {'name_id': 'S00002', 'quantity': '1'}]

I used the following loop to get the values above:

namesequence = EventSequence.objects.filter(description="names").values("Details")

name_quant = [{ 'name_id': e['element'][33:39], 
                        'quantity': e['element'][50:51] } for e in namesequence ]

So my question is how can I aggregate the name_ids and sum the quantities of matching name_ids so that i get a result like so:

 name_sum = [{'name_id': 'S00001', 'quantity': '160'}, {'name_id': 'S00002', 'quantity': '50'}, {'name_id': 'S00003', 'quantity': '40'}, {'name_id': 'S00004', 'quantity': '90'}]

I would have used the sum function in Django but I have to subscript and loop though the value first which makes it a bit more complicated.

Solution

If I understand the question correctly, it looks like the requirement is to consolidate keys (name_id) by quantity. I can’t see how the required output values are derived from the sample input data but that may be because it’s incomplete.

name_quant = [{'name_id': 'S00004', 'quantity': '1'}, {'name_id': 'S00004', 'quantity': '2'}, {'name_id': 'S00003', 'quantity': '1'}, 
 {'name_id': 'S00003', 'quantity': '2'}, {'name_id': 'S00003', 'quantity': '2'}, {'name_id': 'S00002', 'quantity': '1'}]

td = dict()

for e in name_quant:
    nid = e['name_id']
    td[nid] = td.get(nid, 0) + int(e['quantity'])

new_list = [{'name_id': k, 'quantity': str(v)} for k, v in td.items()]

print(new_list)

Output:

[{'name_id': 'S00004', 'quantity': '3'}, {'name_id': 'S00003', 'quantity': '5'}, {'name_id': 'S00002', 'quantity': '1'}]

Answered By – Lancelot du Lac

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published