对满足嵌套键

时间:2018-04-19 21:18:52

标签: python python-3.x dictionary nested

我是新手使用词典,我一直在寻找如何做到这一点,但我找不到这个具体问题的答案。

我有一个4级嵌套字典,在最后一级里面我有感兴趣的值(数组)。它看起来像这样:

import numpy as np

A = np.array([1,2,3])
B = np.array([4,5,6])
C = np.array([7,8,9])
D = np.array([10,11,12])
E = np.array([13,14,15])

d={('domestic','dog','collie','old'):A,
   ('domestic','dog','golden','old'):B,
   ('domestic','dog','golden','young'):C,
   ('domestic','cat','siamese','young'):D,
   ('stray','dog','golden','old'):E}

我需要做的是对满足特定级别某些条件的所有阵列进行操作。

例如,我需要所有在第二级都有“狗”字样的数组的平均值,无论它是国内还是流浪,或者它是旧的还是年轻的等等。

如果我需要一次满足几个条件怎么办?例如,平均所有年轻的狗。

感谢任何帮助!

编辑:我没有使用Pandas的原因是因为我的数组有2个维度,而我正在寻找如何针对每个“关键条件”操作每个(x,y)。我现在用一些答案/评论意识到我的标题问题是不清楚的,我提供的例子是如何显示我真正打算做的。对不起,我应该学会在一整天的工作后不发帖。

在Pandas中,我总是使用平均值而不是所有值,但由于我需要做的是根据某些条件得到一组平均值,我认为这不能用Pandas完成,所以经过一些研究我认为最好的想法是开始使用字典来存储数据。

在我的例子中,我需要获得的是平均值的数组(x0,y0,z0)。例如,如果我想要所有“狗”的平均值& “黄金”,结果应该是

[ (B[0]+C[0])/2, (B[1]+C[1])/2, (B[2]+C[2])/2 ]

使用Pandas可以实现吗?

3 个答案:

答案 0 :(得分:1)

你所拥有的不是嵌套字典,而只是一个由4个值为元组的键组成的字典。嵌套字典更像d={'a':{'b':{'c':{...}}}}。因此,您可以通过迭代或使用d.keys()来获取字典的密钥。例如,如果要平均所有在元组的第二个位置包含单词“dog”的数组:

list = []
for key in d:
    if key[1] == 'dog':
        list.append(d[key])
average = np.mean(list)

使用列表理解可以更简洁地完成:

average = np.mean([d[key] for key in d if key[1]=='dog'])

对于这个问题,我假设你想要对所有数组的所有元素进行完全平均,并且数组的形状都是相同的。

答案 1 :(得分:1)

没有pandas的一种方法是创建一个为您执行此操作的函数。

对于大型数据集,建议仅针对隔离的调用。对于计算的pandas是更好的选择。

import numpy as np

A = np.array([1,2,3])
B = np.array([4,5,6])
C = np.array([7,8,9])
D = np.array([10,11,12])
E = np.array([13,14,15])

d = {('domestic','dog','collie','old'):A,
     ('domestic','dog','golden','old'):B,
     ('domestic','dog','golden','young'):C,
     ('domestic','cat','siamese','young'):D,
     ('stray','dog','golden','old'):E}

def averager(criteria, d):

    def apply_criteria(k, criteria):
        for i, j in criteria.items():
            if k[i] != j:
                return False
        else:
            return True

    return np.mean([v for k, v in d.items() if apply_criteria(k, criteria)], axis=0)

res = averager({0: 'domestic', 1: 'dog'}, d)

# array([ 4.,  5.,  6.])

<强>解释

  • 标准通过averager项字典提供给{index: value}函数。
  • 我们使用列表理解来提取相关的numpy数组值。
  • 使用numpy.meanaxis=0一起计算数组间的索引均值。

答案 2 :(得分:1)

不使用Pandas

>>> from pprint import pprint
>>> import numpy as np
>>> pprint(d)
{('domestic', 'cat', 'siamese', 'young'): array([10, 11, 12]),
 ('domestic', 'dog', 'collie', 'old'): array([1, 2, 3]),
 ('domestic', 'dog', 'golden', 'old'): array([4, 5, 6]),
 ('domestic', 'dog', 'golden', 'young'): array([7, 8, 9]),
 ('stray', 'dog', 'golden', 'old'): array([13, 14, 15])}

过滤字典

>>> keys = ('old','dog')
>>> q = [v for k,v in d.items() if all(thing in k for thing in keys)]
>>> q
[array([1, 2, 3]), array([4, 5, 6]), array([13, 14, 15])]
>>>
>>> #or with keys as a set
>>> keys = set(('old','dog'))
>>> q = [v for k,v in d.items() if len(keys.intersection(k)) == len(keys)]

从结果中创建一个二维数组并获得列的平均值:

>>> np.vstack(q)
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [13, 14, 15]])
>>> np.vstack(q).mean(1)
array([  2.,   5.,  14.])
>>> np.vstack(q).mean(0)
array([ 6.,  7.,  8.])
>>>

使用in运算符,此解决方案不会测试字典键特定位置的值。