汇总与特定对象属性对应的所有值的可靠方法吗?

时间:2018-10-06 14:04:33

标签: python algorithm

我有一个这样的数组。


items = [
  {
    "title": "title1",
    "category": "category1",
    "value": 200
  },
  {
    "title": "title2",
    "category": "category2",
    "value": 450
  },
  {
    "title": "title3",
    "category": "category1",
    "value": 100
  }
]

此数组由许多具有属性categoryvalue的字典组成。 如何获得类别对象数组,其value的总和如下:


data= [
  {
    "category": "category1",
    "value": 300
  },
  {
    "category": "category2",
    "value": 450
  }
]

我正在寻找适用于小型阵列和大型阵列的最佳算法或方法。如果已有算法,请指向源。

我尝试了什么?


data = []
for each item in items:
    if data has a dictionary with dictionary.category == item.category:
        data's dictionary.value = data's dictionary.value + item.value
    else:
        data.push({"category": item.category, "value":item.value})

注意:欢迎使用任何编程语言。请先发表评论,然后再投票。

4 个答案:

答案 0 :(得分:3)

在javascript中,您可以使用reduce将数组分组为一个对象。使用类别作为属性。使用Object.values将对象转换为数组。

var items = [{
    "title": "title1",
    "category": "category1",
    "value": 200
  },
  {
    "title": "title2",
    "category": "category2",
    "value": 450
  },
  {
    "title": "title3",
    "category": "category1",
    "value": 100
  }
];

var data = Object.values(items.reduce((c, v) => {
  c[v.category] = c[v.category] || {category: v.category,value: 0};
  c[v.category].value += v.value;
  return c;
}, {}));

console.log(data);

答案 1 :(得分:1)

您需要的是类似SQL group by的操作。通常,这些group by操作使用哈希算法进行处理。如果所有数据都可以容纳在内存中(小到大的数据结构),则可以非常快地实现它。

如果您的数据结构庞大,则需要使用中间存储器(例如硬盘驱动器或数据库)。

一个简单的python方法将是:

data_tmp = {}
for item in items:
    if item['category'] not in data_tmp:
        data_tmp[item['category']] = 0
    data_tmp[item['category']] += item['value']
data = []
for k, v in data_tmp.items():
    data.append({
        'category': k,
        'value': v
    })
# done

如果您想要更多的Python代码,可以使用defaultdict

from collections import defaultdict
data_tmp = defaultdict(int)
for item in items:
    data_tmp[item['category']] += item['value']
data = []
for k, v in data_tmp.items():
    data.append({
        'category': k,
        'value': v
    })
# done

答案 2 :(得分:1)

在Python中,Pandas可能是一种更方便,更有效的方式。

import pandas as pd
df = pd.DataFrame(items)
sums = df.groupby("category", as_index=False).sum()
data = sums.to_dict("records") 

对于最后一步,将sums保留为数据框并像这样使用它而不是转换回字典列表可能更方便。

答案 3 :(得分:0)

使用 itertools.groupby

d = []

lista = sorted(items, key=lambda x: x['category'])
for k, g in groupby(lista, key=lambda x: x['category']):
    temp = {}
    temp['category'] = k
    temp['value'] = sum([i['value'] for i in list(g)])
    d.append(temp)

print(d)
# [{'category': 'category1', 'value': 300}, {'category': 'category2', 'value': 450}]