计算嵌套dict中的平均值

2024-09-22 16:37:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一本字典,其结构如下:

d = {'actor1': {'salary': {'year1': 60, 'year2': 65}, 'age': 30},
     'actor2': {'salary': {'year1': 20, 'year2': 30}, 'age': 17},
     'actor3': {'salary': {'year1': 50, 'year2': 80}, 'age': 25}}

我希望输出如下:

b = {'average': {'salary': {'year1': 43.3, 'year2': 58.3}, 'age': 24}}

因此,内部dict可以包含同时是数字或字典的值。如果它是一个字典,我们保证每个组成字典都有相同的键(即:对于每个actor,相同的years总是出现在salary中)。你知道吗

我在为age键找到正确的值方面没有问题,可以按以下方式完成

actor_keys = list(d)
b = {}
b['average'] = {}
b['average']['age'] = np.mean([b[i]['age'] for i in actor_keys])

有没有一种类似的计算方法可以聚集在salary中的键上?你知道吗


Tags: age字典数字keys结构dictactoraverage
3条回答

您可以使用递归获得更健壮的解决方案来处理未知深度的输入:

from itertools import groupby
data = {'actor1': {'salary': {'year1': 60, 'year2': 65}, 'age': 30}, 'actor2': {'salary': {'year1': 20, 'year2': 30}, 'age': 17}, 'actor3': {'salary': {'year1': 50, 'year2': 80}, 'age': 25}}
def ave(d):
  _data = sorted([i for b in d for i in b.items()], key=lambda x:x[0])
  _d = [(a, [j for _, j in b]) for a, b in groupby(_data, key=lambda x:x[0])]
  return {a:ave(b) if isinstance(b[0], dict) else round(sum(b)/float(len(b)), 1) for a, b in _d}

result = {'average':ave(list(data.values()))}

输出:

{'average': {'age': 24.0, 'salary': {'year1': 43.3, 'year2': 58.3}}}

我会这么做。你知道吗

def avg(nums):
    nums = list(nums)
    return round(sum(nums) / len(nums), 1)

d = {'actor1': {'salary': {'year1': 60, 'year2': 65}, 'age': 30},
     'actor2': {'salary': {'year1': 20, 'year2': 30}, 'age': 17},
     'actor3': {'salary': {'year1': 50, 'year2': 80}, 'age': 25}}

average = {'salary': {}}
average['age'] = avg(actor['age'] for actor in d.values())
for year in list(d.values())[0]['salary']:
    average['salary'][year] = avg(actor['salary'][year] for actor in d.values())

b = {'average': average}
>>> print(b)
{'average': {'salary': {'year1': 43.3, 'year2': 58.3}, 'age': 24.0}}

这可以处理任意正的年数和参与者数,并且不需要itertoolsnumpy。你知道吗

下面是另一个递归解决方案:

def average_dicts(dicts):
    result = {}
    for i, d in enumerate(dicts):
        for k, v in d.items():
            update_dict_average(result, k, v, i)
    return result

def update_dict_average(current, key, update, n):
    if isinstance(update, dict):
        subcurrent = current.setdefault(key, {})
        for subkey, subupdate in update.items():
            update_dict_average(subcurrent, subkey, subupdate, n)
    else:
        current[key] = (current.get(key, 0) * n + update) / (n + 1)

d = {'actor1': {'salary': {'year1': 60, 'year2': 65}, 'age': 30},
     'actor2': {'salary': {'year1': 20, 'year2': 30}, 'age': 17},
     'actor3': {'salary': {'year1': 50, 'year2': 80}, 'age': 25}}

result = {'average': average_dicts(d.values())}
print(result)
# {'average': {'salary': {'year1': 43.333333333333336, 'year2': 58.333333333333336}, 'age': 24.0}}

相关问题 更多 >