Agrupar por y agregar lista de diccionarios en Python

Tengo una lista de diccionarios que necesito agregar en Python:

data = [{"startDate": 123, "endDate": 456, "campaignName": "abc", "campaignCfid": 789, "budgetImpressions": 10}, {"startDate": 123, "endDate": 456, "campaignName": "abc", "campaignCfid": 789, "budgetImpressions": 50}, {"startDate": 456, "endDate": 789, "campaignName": "def", "campaignCfid": 123, "budgetImpressions": 80}] 

y estoy mirando para agregar basado en presupuestoImpressions.

Entonces el resultado final debería ser:

 data = [{"startDate": 123, "endDate": 456, "campaignName": "abc", "campaignCfid": 789, "budgetImpressions": 60}, {"startDate": 456, "endDate": 789, "campaignName": "def", "campaignCfid": 123, "budgetImpressions": 80}] 

Tenga en cuenta que todas las entradas con un nombre de campaña determinado siempre tendrán la misma campañaCfid, fecha de inicio y fecha de finalización correspondientes.

¿Se puede hacer esto en Python? He intentado usar itertools sin mucho éxito. ¿Sería un mejor enfoque utilizar Pandas?

Sí, usa los pandas. Es genial. Puede usar la funcionalidad groupby y el agregado por sums, luego convierta la salida en una lista de dictados si eso es exactamente lo que desea.

 import pandas as pd data = [{"startDate": 123, "endDate": 456, "campaignName": 'abc', "campaignCfid": 789, "budgetImpressions": 10}, {"startDate": 123, "endDate": 456, "campaignName": 'abc', "campaignCfid": 789, "budgetImpressions": 50}, {"startDate": 456, "endDate": 789, "campaignName": 'def', "campaignCfid": 123, "budgetImpressions": 80}] df = pd.DataFrame(data) grouped = df.groupby(['startDate', 'endDate', 'campaignCfid', 'campaignName']).agg(sum) print grouped.reset_index().to_dict('records') 

Esto imprime:

 [{'startDate': 123L, 'campaignCfid': 789L, 'endDate': 456L, 'budgetImpressions': 60L, 'campaignName': 'abc'}, {'startDate': 456L, 'campaignCfid': 123L, 'endDate': 789L, 'budgetImpressions': 80L, 'campaignName': 'def'}] 

Solo para demostrar que a veces Python está perfectamente bien para hacer este tipo de cosas en:

 In [11]: from collections import Counter from itertools import groupby In [12]: data = [{"startDate": 123, "endDate": 456, "campaignName": "abc", "campaignCfid": 789, "budgetImpressions": 10}, {"startDate": 123, "endDate": 456, "campaignName": "abc", "campaignCfid": 789, "budgetImpressions": 50}, {"startDate": 456, "endDate": 789, "campaignName": "def", "campaignCfid": 123, "budgetImpressions": 80}] In [13]: g = groupby(data, lambda x: x.pop('campaignName')) In [14]: d = {} for campaign, campaign_data in g: c = Counter() for row in campaign_data: c.update(row) d[campaign] = c # if you want a dict rather than Counter, return dict(c) here In [15]: d Out[15]: {'abc': Counter({'campaignCfid': 1578, 'endDate': 912, 'startDate': 246, 'budgetImpressions': 60}), 'def': Counter({'endDate': 789, 'startDate': 456, 'campaignCfid': 123, 'budgetImpressions': 80})} 

Si ya tiene esta colección de listas / diccionarios, no tiene mucho sentido promocionar esto a un Marco de datos, a menudo es más barato permanecer en Python puro.