Friday, 15 April 2011

dictionary - How to reduce/aggregate a list of dicts per multiple keys in Python? -



dictionary - How to reduce/aggregate a list of dicts per multiple keys in Python? -

i have list of dicts this:

sales_per_store_per_day = [ {'date':'2014-06-01', 'store':'a', 'product1':10, 'product2':3, 'product3':15}, {'date':'2014-06-01', 'store':'b', 'product1':20, 'product2':4, 'product3':16}, {'date':'2014-06-02', 'store':'a', 'product1':30, 'product2':5, 'product3':17}, {'date':'2014-06-02', 'store':'b', 'product1':40, 'product2':6, 'product3':18}, ]

how cut down list have sum of products each store, ignoring date? result above input be:

sales_per_store = [ {'store':'a', 'product1':40, 'product2':8, 'product3':32}, {'store':'b', 'product1':60, 'product2':10, 'product3':34} ]

use collections.defaultdict() track info per store, , collections.counter() ease summing of numbers:

from collections import defaultdict, counter by_store = defaultdict(counter) info in sales_per_store_per_day: counts = counter({k: v k, v in info.items() if k not in ('store', 'date')}) by_store[info['store']] += counts sales_per_store = [dict(v, store=k) k, v in by_store.items()]

counts counter() instance built each of products in info dictionary; i'm assuming except store , date keys product counts. uses dict comprehension produce re-create 2 keys removed. by_store[info['store']] looks current total counts given store (which default new, empty counter() object).

the lastly line produces desired output; new dictionaries 'store' , per-product counts, may want maintain dictionary mapping store counter objects.

demo:

>>> collections import defaultdict, counter >>> sales_per_store_per_day = [ ... {'date':'2014-06-01', 'store':'a', 'product1':10, 'product2':3, 'product3':15}, ... {'date':'2014-06-01', 'store':'b', 'product1':20, 'product2':4, 'product3':16}, ... {'date':'2014-06-02', 'store':'a', 'product1':30, 'product2':5, 'product3':17}, ... {'date':'2014-06-02', 'store':'b', 'product1':40, 'product2':6, 'product3':18}, ... ] >>> by_store = defaultdict(counter) >>> info in sales_per_store_per_day: ... counts = counter({k: v k, v in info.items() if k not in ('store', 'date')}) ... by_store[info['store']] += counts ... >>> [dict(v, store=k) k, v in by_store.items()] [{'store': 'a', 'product3': 32, 'product2': 8, 'product1': 40}, {'store': 'b', 'product3': 34, 'product2': 10, 'product1': 60}]

python dictionary

No comments:

Post a Comment