【问题标题】:How to calculate counts and frequencies for pairs in list of lists?如何计算列表列表中对的计数和频率?
【发布时间】:2017-02-25 20:07:17
【问题描述】:

碱基是指A、T、G和C

sample = [['CGG','ATT'],['GCGC','TAAA']]

# Note on fragility of data: Each element can only be made up only 2 of the 4 bases.  
# [['CGG' ==> Only C and G,'ATT' ==> Only A and T],['GCGC'==> Only C and G,'TAAA' ==> Only T and A]]
# Elements like "ATGG" are not present in the data as the have more than 3 different types of bases

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

  1. 分别计算对中每个碱基的频率:

    CGG => (C = 1/3, G = 2/3) ATT => (A = 1/3, T = 2/3)

  2. 计算对中碱基组合的出现频率。在这里,组合是'CA'和'GT'(注意,基本的顺序很重要。不是'CA','AC','GT'和'TG'。只有'CA'和'GT') .

    对 => (CA = 1/3, GT = 2/3)

  3. 计算float(a) = (对的频率) - ((CGG中C的频率) * (ATT中A的频率))

    例如在 CA 对中,float (a) = (CA 对的频率) - ((CGG 中 C 的频率) * (ATT 中 A 的频率))

    输出 a = (1/3) - ((1/3) * (1/3)) = 0.222222

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

注意:如果对是 AAAC 和 CCCA,则 C 的频率将是 1/4,即它是碱基在其中一对上的频率

  1. 计算 b float (b) = (float(a)^2)/ (CGG 中 C 的频率) * (CGG 中 G 的频率) * (ATT 中的频率 A) * (ATT 中 T 的频率)

    Output b = 1
    

对整个列表执行此操作

   Final Output a = [0.2222, - 0.125]
                b = [1, 0.3333]

此代码改编自this answer。请注意,这两个问题存在细微差别,在解决问题的方法上也不相同。

但是,我无法运行此代码。我收到以下错误: 对于配对,计入 i: TypeError: 'int' 对象不可迭代

#Count individual bases.

sample4 = [['CGG','ATT'],['GCGC','TAAA']]
base_counter = Counter()
for i in enumerate(sample4):
    for pair, count in i:
        base_counter[pair[0]] += count
        base_counter[pair[1]] += count
        print base_counter

# Get the total for each base.
total_count = sum(base_counter.values())

# Convert counts to frequencies.
base_freq = {}
for base, count in base_counter.items():
    base_freq[base] = count / total_count
# Not sure how to write a code to count the number of pairs (Step 2)
# Let's say the counts have been stored in pair_counts

# Examine a pair from the two unique pairs to calculate float_a.
for i in enumerate(sample4):
    float(a) = (pair_count[pair] / sum(pair_count.values())) - (base_freq[pair[0]] * base_freq[pair[1]])

# Step 7!
for i in enumerate(sample4):
    float_b = float_a / float(base_freq[0][0] * base_freq[0][1] * base_freq[1][0] * base_freq[1][1])

【问题讨论】:

  • for j in i[0]: ??删除此行。
  • 你使用Counter的方式不如使用普通的dict
  • range 函数返回一个整数列表,因此在您的第一个循环中,每个i 都是一个int。您的错误是因为在嵌套的for 循环中,您试图迭代int。也许您想改用enumerate,或者简单地迭代sample4
  • @Jean-FrançoisFabre:好的,我会
  • @Biotechgeek,是的......您的代码中还有很多其他错误。我认为您应该花时间研究循环在 python 中的工作方式,以及 rangeenumerate 的工作方式。此外,如果您尝试在 REPL 中逐行运行而不是尝试一次运行整个脚本,那么这类事情也会有所帮助。它可以让你看到每一步的输出是什么。

标签: python list dictionary count


【解决方案1】:

您并没有真正使用Counter 与普通的dict 有任何不同。尝试以下方法:

>>> sample = [['CGG','ATT'],['GCGC','TAAA']]
>>> from collections import Counter
>>> base_counts = [[Counter(base) for base in sub] for sub in sample]
>>> base_counts
[[Counter({'G': 2, 'C': 1}), Counter({'T': 2, 'A': 1})], [Counter({'G': 2, 'C': 2}), Counter({'A': 3, 'T': 1})]]

现在您可以继续使用嵌套推导的函数式方法来转换您的数据*:

>>> base_freqs = [[{k_v[0]:k_v[1]/len(bases[i]) for i,k_v in enumerate(count.items())} for count in counts] 
...               for counts, bases in zip(base_counts, sample)]
>>> 
>>> base_freqs
[[{'G': 0.6666666666666666, 'C': 0.3333333333333333}, {'A': 0.3333333333333333, 'T': 0.6666666666666666}], [{'G': 0.5, 'C': 0.5}, {'A': 0.75, 'T': 0.25}]]
>>> 

*注意,有些人不喜欢这样大的、嵌套的推导。我认为只要你坚持使用函数式构造而不是在你的理解中改变数据结构就可以了。我真的觉得它很有表现力。其他人强烈反对。您始终可以将该代码展开到嵌套的 for 循环中。

不管怎样,你可以用这些对来做同样的事情。第一:

>>> pairs = [list(zip(*bases)) for bases in sample]
>>> pairs
[[('C', 'A'), ('G', 'T'), ('G', 'T')], [('G', 'T'), ('C', 'A'), ('G', 'A'), ('C', 'A')]]
>>> pair_counts = [Counter(base_pair) for base_pair in pairs]
>>> pair_counts
[Counter({('G', 'T'): 2, ('C', 'A'): 1}), Counter({('C', 'A'): 2, ('G', 'T'): 1, ('G', 'A'): 1})]
>>> 

现在,这里不使用推导更容易,因此我们不必多次计算total

>>> pair_freq = []
>>> for count in pair_counts:
...   total = sum(count.values())
...   pair_freq.append({k:c/total for k,c in count.items()})
... 
>>> pair_freq
[{('C', 'A'): 0.3333333333333333, ('G', 'T'): 0.6666666666666666}, {('G', 'T'): 0.25, ('C', 'A'): 0.5, ('G', 'A'): 0.25}]
>>> 

【讨论】:

  • 但是,如果我使用这种方法,我不清楚如何提取所需的值并计算 a 的值。第 3 步。这是您通过理解的方式吗float a = {k: float(pair_freq[k][0]) - base_freqs[k][0] * base_freqs[k][1]for k in pair_freq.viewkeys() & base_freqs.viewkeys()}
  • 另外,如果可以的话..你能把base_freqs理解分解成一堆for循环吗?我对理解比较陌生,当我试图理解代码的逻辑时我发现很难
猜你喜欢
  • 2016-05-20
  • 2020-03-10
  • 1970-01-01
  • 1970-01-01
  • 2020-12-29
  • 2023-04-05
  • 2019-06-14
  • 2017-01-27
  • 1970-01-01
相关资源
最近更新 更多