【问题标题】:list of dictionary: aggregate value by grouping by inner dictionary key字典列表:按内部字典键分组聚合值
【发布时间】:2020-02-18 01:19:43
【问题描述】:

我有这个签名:

def aggregate_by_player_id(input, playerid, fields):

“字段”是指在“输入”中按“玩家ID”分组的字段。

我这样调用函数:

aggregate_by_player_id(input, 'player', ['stat1','stat3'])

输入如下所示:

[{'player': '1', 'stat1': '3', 'stat2': '4', 'stat3': '5'},
{'player': '1', 'stat1': '1', 'stat2': '4', 'stat3': '1'},
{'player': '2', 'stat1': '1', 'stat2': '2', 'stat3': '3'},
{'player': '2', 'stat1': '1', 'stat2': '2', 'stat3': '1'},
{'player': '3', 'stat1': '4', 'stat2': '1', 'stat3': '6'}]

我的输出结构是:

nested_dic = {value_of_playerid1: {'playerid': value_of_playerid1, 'stat1': value_of_stat1, 'stat2': value_of_stat2}, 
              value_of_playerid2: {'playerid': value_of_playerid2, 'stat2': value_of_stat2, 'stat2': value_of_stat2}, 
              value_of_playerid3: {'playerid': value_of_playerid3, 'stat3': value_of_stat3, 'stat3': value_of_stat3}}

因此输出应如下所示:

{'1': {'player': '1', 'stat1': 4, 'stat3': 6}, 
 '2': {'player': '2', 'stat1': 2, 'stat3': 4}, 
 '3': {'player': '3', 'stat1': 4, 'stat3': 6}} 

【问题讨论】:

  • 您似乎正在寻找对字典 ('stat1','stat3') 的属性进行 sum 以获得与其他属性 ('player') 具有匹配值的所有条目?您是否查看过字典理解并自己尝试过任何东西?
  • 你好。我尝试总结('stat1','stat3')每个playerID。我尝试了很多 for 循环。我最终将所有玩家相加或仅重新计算最后一个......
  • 如果你有熊猫,这其实很简单。
  • 我不知道 pandas 但我可以学习...我是 python 的初学者,但我会尽力而为
  • 啊,那是nvm。我不建议只为一项特定任务打开一个全新的库。它适用于数据重塑、转换和聚合,因此您可能希望将来牢记它的存在。

标签: python list dictionary aggregate


【解决方案1】:

我们可以为此使用itertools.groupbyplayerid 进行分组,然后对各个字段的值求和。

from itertools import groupby
from operator import itemgetter

def aggregate_by_player_id(input_, playerid, fields):
    player = itemgetter(playerid)
    output = {}

    for k, v in groupby(input_, key=player):
        data = list(v)
        stats = {playerid: k}

        for field in fields:
            stats[field] = sum(int(d.get(field, 0)) for d in data)
        output[k] = stats
    return output

data.sort(key=player) # data must be pre-sorted on grouping key
results = aggregate_by_player_id(data, 'player', ['stat1', 'stat3'])

{'1': {'player': '1', 'stat1': 4, 'stat3': 6},
 '2': {'player': '2', 'stat1': 2, 'stat3': 4},
 '3': {'player': '3', 'stat1': 4, 'stat3': 6}}

【讨论】:

    【解决方案2】:

    在一个单一的理解中捕获您所追求的结果可能是可能的,但可能不是很可读。这是一个可以完成工作的简单函数:

    data = [
        {'player': '1', 'stat1': '3', 'stat2': '4', 'stat3': '5'},
        {'player': '1', 'stat1': '1', 'stat2': '4', 'stat3': '1'},
        {'player': '2', 'stat1': '1', 'stat2': '2', 'stat3': '3'},
        {'player': '2', 'stat1': '1', 'stat2': '2', 'stat3': '1'},
        {'player': '3', 'stat1': '4', 'stat2': '1', 'stat3': '6'}
    ]
    
    
    def aggregate_dicts(ds, id_field, aggr_fields):
        result = {}
        for d in ds:
            identifier = d[id_field]
            if identifier not in result:
                result[identifier] = {f: 0 for f in aggr_fields}
            for f in aggr_fields:
                result[identifier][f] += int(d[f])
        return result
    
    
    print(aggregate_dicts(data, 'player', ['stat1', 'stat3']))
    

    结果:

    {'1': {'stat1': 4, 'stat3': 6}, '2': {'stat1': 2, 'stat3': 4}, '3': {'stat1': 4, 'stat3': 6}}
    

    如果要在字典中重复标识符,只需将此行添加到if 块:

                result[identifier][id_field] = identifier
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-03
      • 1970-01-01
      相关资源
      最近更新 更多