【问题标题】:How to extract and divide values from dictionary with another in Python?python - 如何在Python中从字典中提取和划分值?
【发布时间】:2016-10-17 01:10:11
【问题描述】:
sample = [['CGG','ATT'],['GCGC','TAAA']]

#Frequencies of each base in the pair
d1 = [[{'G': 0.66, 'C': 0.33}, {'A': 0.33, 'T': 0.66}], [{'G': 0.5, 'C': 0.5}, {'A': 0.75, 'T': 0.25}]]

#Frequencies of each pair occurring together

d2 = [{('C', 'A'): 0.33, ('G', 'T'): 0.66}, {('G', 'T'): 0.25, ('C', 'A'): 0.5, ('G', 'A'): 0.25}]

问题:

考虑第一对:['CGG','ATT']

如何计算a,其中a是:

float(a) = (freq of pairs) - ((freq of C in CGG) * (freq of A in ATT))

eg. in CA pairs, float (a) = (freq of CA pairs) - ((freq of C in CGG) * (freq of A in ATT))

Output a = (0.33) - ((0.33) * (0.33)) = 0.222222

计算任何一个组合的“a”(CA 对或 GT 对)

Final Output for sample : a = [0.2222, - 0.125]

如何计算b,其中b是:

float (b) = (float(a)^2)/ (freq of C in CGG) * (freq G in CGG) * (freq A in ATT) * (freq of T in ATT)

Output b = 1

对整个列表执行此操作

Final Output for sample : b = [1, 0.3333]

我不知道如何从 d1 和 d2 中提取所需的值并执行数学运算。

我尝试为 a 的值编写以下代码

float a = {k: float(d1[k][0]) - d2[k][0] * d2[k][1]for k in d1.viewkeys() & d2.viewkeys()}

但是,它不起作用。另外,我更喜欢 for 循环而不是推导式

我尝试为上述内容编写(一个相当有缺陷的)for循环:

float_a = []
for pair,i in enumerate(d2):
    for base,j in enumerate(d1):
        float (a) = pair[i][0] - base[j][] * base[j+1][]
        float_a.append(a)

float_b = []
  for floata in enumerate(float_a):
    for base,j in enumerate(d1):
        float (b) = (float(a) * float(a)) - (base[j] *    base[j+1]*base[j+2]*base[j+3])
        float_b.append(b)

【问题讨论】:

  • 第一次组合a = d2[0][0][('C','A')] - d1[0][0]['C'] * d1[0][1]['A']
  • 你试过那些简单的(嵌套的)for循环吗?甚至可能以最简单的方式,迭代索引而不是值。让它工作,然后你就可以开始重构了。
  • 当我计算sample 列表中第二项的“a”值(即['GCGC','TAAA'])时,我得到两个不同的“a”值(CA = GT = 0.125 ,GA = -0.125)。选择样本的最终“a”输出为 -0.125 而不是 +0.125 时,是否有任何理由?
  • @furas 我需要一个通用的循环,而不是一个特定的循环
  • @user2588654 我选择哪个“a”并不重要,因为值将是相同的(正如您计算的那样),并且在计算 b 时,我将“a”的值平方,所以问题的标志消失。对于我的程序,我终于需要 b 的值

标签: python list dictionary counter


【解决方案1】:

通常,当遇到这样的棘手问题时,需要使用多个公式和中间步骤,我喜欢通过将工作拆分为多个函数来对其进行模块化。以下是处理原始问题和 cmets 中案例的结果注释代码:

from collections import Counter

def get_base_freq(seq):
    """
    Returns the normalized frequency of each base in a given sequence as a dictionary.
    A dictionary comprehension converts the Counter object into a "normalized" dictionary.
    """
    seq_len = len(seq)
    base_counts = Counter(seq)
    base_freqs = {base: float(count)/seq_len for base, count in base_counts.items()}
    return base_freqs

def get_pair_freq(seq1, seq2):
    """
    Uses zip to merge two sequence strings together.
    Then performs same counting and normalization as in get_base_freq.
    """
    seq_len = len(seq1)
    pair_counts = Counter(zip(seq1, seq2))
    pair_freqs = {pair: float(count)/seq_len for pair, count in pair_counts.items()}
    return pair_freqs

def calc_a(d1, d2):
    """
    Arbitrarily takes the first pair in d2 and calculates the a-value from it.
    """
    first_pair, pair_freq = d2.items()[0]
    base1, base2 = first_pair
    a = pair_freq - (d1[0][base1]*d1[1][base2])
    return a

def calc_b(a, d1):
    """
    For this calculation, we need to use all of the values from d1 and multiply them together.
    This is done by merging the two sequence half-results together and multiplying in a for loop.
    """
    denom_ACGT = d1[0].values() + d1[1].values()
    denom = 1
    for val in denom_ACGT:
        denom *= val
    b = a*a/float(denom)
    return b

if __name__ == "__main__":
    sample = [['CGG','ATT'], ['GCGC','TAAA'], ['ACAA','CAAC']]
    b_result = []
    for seq_pair in sample:
        d1 = [get_base_freq(seq) for seq in seq_pair]
        d2 = get_pair_freq(*seq_pair)
        a = calc_a(d1, d2)
        b = calc_b(a, d1)
        b_result.append(b)
    print b_result

让我知道是否需要清理任何东西,或者如果我没有考虑过的情况下它失败了!

【讨论】:

  • 这很好用!如果我有任何修改,我一定会告诉你
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-26
  • 2023-03-17
  • 2011-10-23
  • 1970-01-01
  • 2022-01-25
  • 2021-09-03
  • 1970-01-01
相关资源
最近更新 更多