Групповой и сводный список словарей в Python

97
10

У меня есть список словарей, которые мне нужно заполнить в 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}]

и я собираюсь агрегировать на основе budgetImpressions.


Итак, конечный результат должен быть:


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

Обратите внимание, что каждая запись с определенным именем campaign всегда будет иметь те же соответствующие campaignCfid, startDate и endDate.


Можно ли это сделать на Python? Я пробовал использовать itertools без особого успеха. Будет ли лучший подход к использованию Pandas?

спросил(а) 2021-01-19T12:40:31+03:00 2 месяца, 3 недели назад
1
Решение
87

Просто, чтобы продемонстрировать, что иногда python отлично подходит для создания такого рода вещей:


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})}

Если у вас уже есть эта коллекция списков /dicts, на самом деле не имеет смысла продвигать это в DataFrame, часто дешевле оставаться в чистом питоне.

ответил(а) 2021-01-19T12:40:31+03:00 2 месяца, 3 недели назад
44

Да, используйте pandas. Это здорово. Вы можете использовать функциональность groupby и совокупность по суммам, а затем преобразовать вывод в список dicts, если это именно то, что вы хотите.


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')

Отпечатки:


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

ответил(а) 2021-01-19T12:40:31+03:00 2 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема