Python中的字典分组和聚合列表

Posted

技术标签:

【中文标题】Python中的字典分组和聚合列表【英文标题】:Group By & Aggregate List of Dictionaries in Python 【发布时间】:2014-08-03 10:51:55 【问题描述】:

我有一个需要在 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]

请注意,具有特定campaignName 的每个条目将始终具有相同的对应campaignCfid、startDate 和endDate。

这可以在 Python 中完成吗?我试过使用 itertools 没有太大的成功。使用 Pandas 会更好吗?

【问题讨论】:

预算印象是否会成为您要汇总的词典的唯一不同元素? 这背后的逻辑是什么? @Bryan 是的,只是汇总budgetImpressions @ToClickorNottoClick 逻辑是聚合budgetImpressions 【参考方案1】:

只是为了证明有时 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)

如果你已经有这个列表/字典的集合,那么将它推广到 DataFrame 并没有什么意义,留在纯 python 中通常更便宜。

【讨论】:

此解决方案错误地计算了所有键,而不仅仅是budgetImpressions x.pop('campaignName') 在这里做什么? @Sankalp pop 从字典中查找一个值并删除该键。这意味着campaignName 不会出现在结果计数器中。【参考方案2】:

是的,使用熊猫。这很棒。您可以使用groupby 功能并按总和进行聚合,然后将输出转换为字典列表(如果这正是您想要的)。

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

【讨论】:

为什么所有值都附加一个“L”? 它们是长整数。 @bananafish 有点奇怪,它们的整数很长,我实际上无法复制它。你用的是什么版本的python、numpy、……? @AndyHayden pandas 0.13.1,Windows 上的 numpy 1.8.1,使用来自 here 的 numpy-MKL @bananafish 我猜这是 Windows 而不是 MKL。

以上是关于Python中的字典分组和聚合列表的主要内容,如果未能解决你的问题,请参考以下文章

Python:字典的分组和聚合列表[无计数器]

Python Pandas:如何将列中的分组列表作为字典返回

Python分组

按两个参数对字典列表进行分组并计算分组值

如何修复 BigQuery 中的错误“选择列表表达式 [...] 既不分组也不聚合的引用”?

python 计算数字中的每个数字和非间隔字符串中的每个字母。将它们分组为字典并打印字典。