Средневзвешенное значение для 2 кортежей, каждый из которых имеет 2 словаря (словарей) - PullRequest
1 голос
/ 02 января 2012

Каков будет самый простой / самый короткий / самый-пифонический способ получить средневзвешенное значение a и b?

a = (
        {
          0: {'P': 0.3, 'Z': 0.3, 'N': 0.3}, 
        'P': {'P': 0.9, 'Z': 0.1, 'N': 0.0}, 
        'Z': {'P': 0.1, 'Z': 0.9, 'N': 0.1}, 
        'N': {'P': 0.0, 'Z': 0.1, 'N': 0.9}
        },

        {
         'P': {'A': 0.3, 'C': 0.3, 'T': 0.2, 'G': 0.2}, 
         'Z': {'A': 0.3, 'C': 0.3, 'T': 0.2, 'G': 0.2}, 
         'N': {'A': 0.3, 'C': 0.3, 'T': 0.2, 'G': 0.2}
        }
    )

b = (
        {
          0: {'P': 0.3, 'Z': 0.3, 'N': 0.3}, 
        'P': {'P': 0.3, 'Z': 0.3, 'N': 0.3}, 
        'Z': {'P': 0.3, 'Z': 0.3, 'N': 0.3}, 
        'N': {'P': 0.3, 'Z': 0.3, 'N': 0.3}
        },

        {
         'P': {'A': 0.25, 'C': 0.25, 'T': 0.25, 'G': 0.25}, 
         'Z': {'A': 0.25, 'C': 0.25, 'T': 0.25, 'G': 0.25}, 
         'N': {'A': 0.25, 'C': 0.25, 'T': 0.25, 'G': 0.25}
        }
    )

, чтобы в результате c = [(a * a_weight) + (b * b_weight) / (a_weight + b_weight)] должен иметь такую ​​же структуру (как a и b).

Если кто-нибудь знает ответ Pythonic, спасибо.

Пример полученной структуры c

Например, если a_weight = b_weight = 0,5 (простое среднее значение), тогда c первая 'P': строка

'P': {'P': (0.9 + 0.3) / 2, 'Z': (0.1 + 0.3) / 2, 'N': (0.0 + 0.3) / 2}

будет в среднем

a * 'P': {'P': 0.9, 'Z': 0.1, 'N': 0.0}и
b * 'P': {'P': 0.3, 'Z': 0.3, 'N': 0.3}.

По сути, в среднем всего value с (при этом каждый key остается без изменений).

1 Ответ

2 голосов
/ 02 января 2012

Я бы сделал функцию, которая принимает два входа и рекурсивно их преобразует в соответствии с их типом:

def combine(a, b, a_weight, b_weight):
    if isinstance(a, tuple):
        return tuple(combine(x,y,a_weight,b_weight) for x,y in zip(a,b))
    elif isinstance(a, dict):
        return dict((k, combine(a[k],b[k],a_weight,b_weight)) for k in a)
    #add other data structures here if you need to (e.g. list, set, etc.)
    else: #assume a number
        return ((a * a_weight) + (b * b_weight)) / (a_weight + b_weight)

Приятной особенностью этого метода является то, что он будет продолжать работать, даже если вы измените структуру входов.

Обратите внимание, что в этом коде предполагается, что структура a и b одинакова, кортежи имеют одинаковое количество элементов, а словари имеют одинаковые ключи. Если это не всегда так, вам нужно добавить код, чтобы проверить это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...