Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将外部关键字分组后,查找内部字典关键字的平均值_Python_Dictionary - Fatal编程技术网

Python 将外部关键字分组后,查找内部字典关键字的平均值

Python 将外部关键字分组后,查找内部字典关键字的平均值,python,dictionary,Python,Dictionary,我有一本嵌套字典 dictionary = {'cat_1' : {'age' : 5, 'height' : 15}, 'cat_2' : {'age' : 1, 'height' : 7}, 'dog_1' : {'age' : 13, 'height' : 20}, 'dog_2' : {'age' : 9, 'height' : 18}} 我想通过对外部id键进行分组(使用类似于key.split(“”“)[0])的方法,找到每种动物的内部字典键的平均值。类似的方法可能会: di

我有一本嵌套字典

dictionary =  {'cat_1' : {'age' : 5, 'height' : 15}, 'cat_2' :  {'age' : 1, 'height' : 7}, 'dog_1' : {'age' : 13, 'height' : 20}, 'dog_2' :  {'age' : 9, 'height' : 18}}

我想通过对外部id键进行分组(使用类似于
key.split(“”“)[0]
)的方法,找到每种动物的内部字典键的平均值。

类似的方法可能会:

dictionary =  {'cat_1' : {'age' : 5, 'height' : 15}, 'cat_2' :  {'age' : 1, 'height' : 7}, 'dog_1' : {'age' : 13, 'height' : 20}, 'dog_2' :  {'age' : 9, 'height' : 18}}

cats = dict((k, v) for k, v in dictionary.items() if k.startswith("cat"))

cat_count = len(cats)
cat_average_ages = sum([cats[k]["age"] for k in cats]) / cat_count
cat_average_heights = sum([cats[k]["height"] for k in cats]) / cat_count
您可以为狗复制该值,或创建一个返回平均值的函数,具体取决于您有多少种不同的动物:

def find_average_values(animals_dict, animal_name="cat"):
    animals = dict((k, v) for k, v in dictionary.items() if k.startswith(animal_name))

    animal_count = len(animals)
    animal_average_ages = sum([animals[k]["age"] for k in animals]) / animal_count
    animal_average_heights = sum([animals[k]["height"] for k in animals]) / animal_count

    return {"age": animal_average_ages, "height": animal_average_heights}

dog_averages = find_average_values(dictionary, "dog")

这个怎么样,它使用
Pandas

import pandas as pd

df = pd.DataFrame.from_records(dictionary)

        cat_1  cat_2  dog_1  dog_2
age         5      1     13      9
height     15      7     20     18

df = df.T.reset_index()

   index  age  height
0  cat_1    5      15
1  cat_2    1       7
2  dog_1   13      20
3  dog_2    9      18

df['index'] = [elem.split('_',1)[0] for elem in df['index']]

  index  age  height
0   cat    5      15
1   cat    1       7
2   dog   13      20
3   dog    9      18

df.groupby('index').mean().T

index   cat  dog
age       3   11
height   11   19
如果输出需要是字典,则:

df.groupby('index').mean().T.to_dict()

{'cat': {'age': 3, 'height': 11}, 'dog': {'age': 11, 'height': 19}}

您可以使用
itertools
模块中的
sum()和
groupby
执行类似操作:

from itertools import groupby

a = {'cat_1' : {'age' : 5, 'height' : 15}, 'cat_2' :  {'age' : 1, 'height' : 7}, 'dog_1' : {'age' : 13, 'height' : 20}, 'dog_2' :  {'age' : 9, 'height' : 18}}

animals, final = {}, {}

for k,v in groupby(sorted(a.items(), key=lambda x:x[0].split('_')[0]), lambda x: x[0].split('_')[0]):
    animals[k] = [j for _, j in list(v)]


for k in animals:
    final[k] = {"height": sum(j["height"] for j in animals[k])/len(animals[k]),
    "age": sum(j["age"] for j in animals[k])/len(animals[k])}

print(final)
输出:

{'cat': {'height': 11.0, 'age': 3.0}, 'dog': {'height': 19.0, 'age': 11.0}}

另一个答案是使用
itertools.groupby
collections.defaultdict
。还有一个额外的好处,就是不需要知道你的内部dict键

from itertools import groupby
from collections import defaultdict

d =  {'cat_1' : {'age' : 5, 'height' : 15}, 'cat_2' :  {'age' : 1, 'height' : 7}, 'dog_1' : {'age' : 13, 'height' : 20}, 'dog_2' :  {'age' : 9, 'height' : 18}}
res = defaultdict(lambda : defaultdict(int))

# Group inner dicts by key
for k, g in groupby(d.items(), lambda t: t[0].split('_')[0]):
    for _, inner in g:
        # total the values
        for key, value in inner.items():
            res[k][key] += value

    # for each key average by the length of the dict
    res[k] = { _k : _v / len(inner) for _k, _v in res[k].items() }

不需要手动指定键的另一个选项是:

from collections import Counter, defaultdict
from itertools import groupby, chain

dictionary = {'cat_1' : {'age' : 5, 'height' : 15},
              'cat_2' : {'age' : 1, 'height' : 7},
              'dog_1' : {'age' : 13, 'height' : 20},
              'dog_2' : {'age' : 9, 'height' : 18}}

animals_grouped = groupby(sorted(dictionary.items(),
                                 key=lambda x: x[0].split('_')[0]),
                          key=lambda x: x[0].split('_')[0])

animals_data_average = defaultdict(dict)

for animal in animals_grouped:
    animal_data_list   = list(chain.from_iterable(list(animal_data[1].items()) for animal_data in animal[1]))
    animal_key_counter = Counter([animal_data[0] for animal_data in animal_data_list])

    for data_key in animal_key_counter:
        animals_data_average[animal[0]][data_key] = sum([animal_data[1] for animal_data in animal_data_list if animal_data[0] == data_key]) / animal_key_counter[data_key]

print(dict(animals_data_average))

你试过什么?此外,您能否概述所需的输出?我没有得到
split[''.][0]
的部分。我想OP的意思是
key.split('.''.[0]
,它会给你动物类型这甚至不是一个完整的answer@DmitryPolonskiy你是什么意思?你只包括了如何计算字典中的一个键,而不是两个键,简单地说
你可以为狗复制它或创建一个函数
并不是一个完整的答案。答案的输出应该是所有键的平均值。如果有马,甚至是动物你事先不知道怎么办?使用
熊猫
的方法很好,但是(在我的框中)需要一些时间来完成数据处理。但是,这仍然是一个很好的答案+1.@ChihebNexus,你的数据集有多大?@Setop我真的不知道。我用的是一个2GB内存的旧双核,花了点时间?这个数据非常小,我几乎没有花时间。@ChihebNexus,对不起。我以为这是OP的评论。因为我无法想象熊猫在4张唱片的口述中表现得很慢。这没什么。我曾经处理过数百万张没有任何问题的唱片。Pandas使用C语言编写的numpy作为关键部件,因此速度非常快,内存效率也非常高。