代码之家  ›  专栏  ›  技术社区  ›  lanadaquenada

对满足嵌套键中条件的字典的所有值进行操作

  •  1
  • lanadaquenada  · 技术社区  · 8 年前

    我对使用字典很陌生,我一直在寻找如何做到这一点,但我找不到这个具体问题的答案。

    我有一个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}
    

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

    例如,我需要在第二级中包含单词“dog”的所有数组的平均值,无论它是家里的还是流浪的,或者它是老的还是年轻的,等等。

    如果我需要同时满足几个条件呢?例如,所有幼犬的平均值。

    感谢您的帮助!

    编辑:我没有使用Pandas的原因是因为我的数组有两个维度,我正在研究如何针对每个“关键条件”在每个(x,y)上进行操作。现在,通过一些回答/评论,我意识到我的标题问题不清楚,我提供的示例没有显示我真正打算做什么。对此我很抱歉,我应该在工作了一天之后学会不发帖。

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

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

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

    这是否可能通过使用熊猫来实现?

    3 回复  |  直到 8 年前
        1
  •  1
  •   jpp    8 年前

    单程无 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} 项目。
    • 我们使用列表a理解来提取相关 numpy 数组值。
    • 使用 numpy.mean 具有 axis=0 通过数组中的索引计算平均值。
        2
  •  1
  •   enumaris    8 年前

    这里没有嵌套字典,只是一个由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'])
    

    对于这个问题,我假设您需要所有数组的所有元素的完全平均值,并且数组的形状都相同。

        3
  •  1
  •   wwii    8 年前

    不使用熊猫

    >>> 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 运算符,此解决方案不会测试字典键特定位置的值。