【问题标题】:Python how to add sums of multiple listsPython如何添加多个列表的总和
【发布时间】:2019-05-01 14:21:03
【问题描述】:

以下是列表列表。如何将“Total Black”和“Total Color”的总和添加到一个列表中,同时保持“Account ID”和“Account Name”相同?

[[{'Total Black': 3, 'Total Color': 2, 'Account ID': '2222', 'Account Name': 'Moe'}, 
  {'Total Black': 5, 'Total Color': 4, 'Account ID': '3333', 'Account Name': 'Larry'}, 
  {'Total Black': 9, 'Total Color': 6, 'Account ID': '4444', 'Account Name': 'Curly'}], 
 [{'Total Black': 8, 'Total Color': 4, 'Account ID': '2222', 'Account Name': 'Moe'}, 
  {'Total Black': 2, 'Total Color': 7, 'Account ID': '3333', 'Account Name': 'Larry'}, 
  {'Total Black': 11, 'Total Color': 9, 'Account ID': '4444', 'Account Name': 'Curly'}]]

所以结果是:

[{'Total Black': 11, 'Total Color': 6, 'Account ID': '2222', 'Account Name': 
'Moe'}, {'Total Black': 7, 'Total Color': 11, 'Account ID': '3333', 'Account 
Name': 'Larry'}, {'Total Black': 20, 'Total Color': 15, 'Account ID': 4444, 
'Account Name': 'Curly'}]

【问题讨论】:

  • 那么想要的结果是什么?
  • 欢迎来到 Stackoverflow。请填写您的tour 并咨询How to Ask 部分,了解什么是好问题。首先,minimal reproducible example 表明您尝试显示失败的位置和预期结果。
  • 结果将是 [{'Total Black': 11, 'Total Color': 6, 'Account ID': '2222', 'Account Name': 'Moe'}, {'Total Black ': 7, 'Total Color': 11, 'Account ID': '3333', 'Account Name': 'Larry'}, {'Total Black': 20, 'Total Color': 15, 'Account ID': 4444, '帐户名称': '卷曲'}]
  • @Brotherhero 检查我的解决方案是否没有 pandas 解决方案。

标签: python pandas


【解决方案1】:

设置

thing = [
    [{'Total Black': 3, 'Total Color': 2, 'Account ID': '2222', 'Account Name': 'Moe'}, 
     {'Total Black': 5, 'Total Color': 4, 'Account ID': '3333', 'Account Name': 'Larry'}, 
     {'Total Black': 9, 'Total Color': 6, 'Account ID': '4444', 'Account Name': 'Curly'}], 
    [{'Total Black': 8, 'Total Color': 4, 'Account ID': '2222', 'Account Name': 'Moe'}, 
     {'Total Black': 2, 'Total Color': 7, 'Account ID': '3333', 'Account Name': 'Larry'}, 
     {'Total Black': 11, 'Total Color': 9, 'Account ID': '4444', 'Account Name': 'Curly'}]
]

与 ScottBoston 非常相似

pd.DataFrame(sum(thing, [])).groupby(
    ['Account ID', 'Account Name'], as_index=False
).sum().to_dict('r')

merge_with

from itertools import chain
from toolz.dicttoolz import merge_with
from collections import defaultdict

idkey = ('Account ID', 'Account Name')

x = defaultdict(list)
for d in map(dict, chain(*thing)):
  x[(*map(d.pop, idkey),)].append(d)

[{**dict(zip(idkey, key)), **merge_with(sum, *d)} for key, d in x.items()]

[{'Account ID': '2222',
  'Account Name': 'Moe',
  'Total Black': 11,
  'Total Color': 6},
 {'Account ID': '3333',
  'Account Name': 'Larry',
  'Total Black': 7,
  'Total Color': 11},
 {'Account ID': '4444',
  'Account Name': 'Curly',
  'Total Black': 20,
  'Total Color': 15}]

【讨论】:

  • 就是这样,不是吗?
  • 大声笑哦..现在这太有趣了。 “总结” 好的,Smartypants 先生。给我解释一下语法。
  • [] 告诉 sum 要添加的起始对象是一个空列表。
  • 啊...将列表的列表扁平化为列表?
【解决方案2】:

让我们使用熊猫。

#From @C14L setup:

li = [
    [
        {'Total Black': 3, 'Total Color': 2, 'Account ID': '2222', 'Account Name': 'Moe'},
        {'Total Black': 5, 'Total Color': 4, 'Account ID': '3333', 'Account Name': 'Larry'},
        {'Total Black': 9, 'Total Color': 6, 'Account ID': '4444', 'Account Name': 'Curly'}
    ],
    [
        {'Total Black': 8, 'Total Color': 4, 'Account ID': '2222', 'Account Name': 'Moe'},
        {'Total Black': 2, 'Total Color': 7, 'Account ID': '3333', 'Account Name': 'Larry'},
        {'Total Black': 11, 'Total Color': 9, 'Account ID': '4444', 'Account Name': 'Curly'}
    ]
]

pd.concat([pd.DataFrame(li[i]) for i in range(len(li))])\
  .groupby(['Account ID','Account Name'])\
  .sum()\
  .reset_index()\
  .to_dict(orient='records')

输出:

[{'Account ID': '2222',
  'Account Name': 'Moe',
  'Total Black': 11,
  'Total Color': 6},
 {'Account ID': '3333',
  'Account Name': 'Larry',
  'Total Black': 7,
  'Total Color': 11},
 {'Account ID': '4444',
  'Account Name': 'Curly',
  'Total Black': 20,
  'Total Color': 15}]

详情:

首先,我们使用列表推导和 pandas 数据框构造函数为原始列表列表中的每个元素构建数据框和字典。

接下来,使用 pd.concat 将这两个数据帧(在本例中为数据帧)放在一个组合数据帧中。

使用 groupby 和 sum 来聚合 Total Color 和 Total Black 的值。

最后,重置 index 和 to_dict 以将组合数据帧输出为字典。

【讨论】:

  • 最复杂的熊猫公式我永远也想不出来,非常感谢!!!
  • 不客气,我将其合并为一个语句,但您可以将其拆分并单独运行每个方法以查看到底发生了什么。
【解决方案3】:
li = [
    [
        {'Total Black': 3, 'Total Color': 2, 'Account ID': '2222', 'Account Name': 'Moe'},
        {'Total Black': 5, 'Total Color': 4, 'Account ID': '3333', 'Account Name': 'Larry'},
        {'Total Black': 9, 'Total Color': 6, 'Account ID': '4444', 'Account Name': 'Curly'}
    ],
    [
        {'Total Black': 8, 'Total Color': 4, 'Account ID': '2222', 'Account Name': 'Moe'},
        {'Total Black': 2, 'Total Color': 7, 'Account ID': '3333', 'Account Name': 'Larry'},
        {'Total Black': 11, 'Total Color': 9, 'Account ID': '4444', 'Account Name': 'Curly'}
    ]
]

result = [
    {
        'sum': x['Total Black'] + x['Total Color'],
        'Account ID': x['Account ID'],
        'Account Name': x['Account Name']
    } for x in li[0]
]

给出第一个子列表的结果

[
    {'sum': 5, 'Account ID': '2222', 'Account Name': 'Moe'},
    {'sum': 9, 'Account ID': '3333', 'Account Name': 'Larry'},
    {'sum': 15, 'Account ID': '4444', 'Account Name': 'Curly'},
]

这就是你要找的吗?

现在您只需要遍历外部列表以对每个包含的列表重复此操作。

【讨论】:

    【解决方案4】:

    没有 Pandas 解决方案:

    from itertools import groupby
    from operator import itemgetter
    
    orders_list = [[{'Total Black': 3, 'Total Color': 2, 'Account ID': '2222', 'Account Name': 'Moe'}, 
      {'Total Black': 5, 'Total Color': 4, 'Account ID': '3333', 'Account Name': 'Larry'}, 
      {'Total Black': 9, 'Total Color': 6, 'Account ID': '4444', 'Account Name': 'Curly'}], 
     [{'Total Black': 8, 'Total Color': 4, 'Account ID': '2222', 'Account Name': 'Moe'}, 
      {'Total Black': 2, 'Total Color': 7, 'Account ID': '3333', 'Account Name': 'Larry'}, 
      {'Total Black': 11, 'Total Color': 9, 'Account ID': '4444', 'Account Name': 'Curly'}]]
    
    
    result_list = []
    
    flattened_list = [item for sublist in orders_list for item in sublist]
    grouper = itemgetter("Account ID", "Account Name")
    
    for key, grp in groupby(sorted(flattened_list, key = grouper), grouper):
        temp_dict = dict(zip(["Account ID", "Account Name"], key))
        total_black_count = 0
        total_colors_count = 0
        for element in grp:
              total_black_count += element['Total Black']
              total_colors_count += element['Total Color']
    
        temp_dict["Total Color"] = total_colors_count
        temp_dict["Total Black"] = total_black_count
        result_list.append(temp_dict)
    
    for dictionary in result_list:
        for key, values in dictionary.items():
            print(f"{key}: {values}")
    

    DEMO FIDDLE

    【讨论】:

      猜你喜欢
      • 2016-04-25
      • 2013-07-28
      • 1970-01-01
      • 1970-01-01
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多