如何计算Python中列表成对比较的元素频率?

Posted

技术标签:

【中文标题】如何计算Python中列表成对比较的元素频率?【英文标题】:How to calculate frequency of elements for pairwise comparisons of lists in Python? 【发布时间】:2017-02-25 06:14:07 【问题描述】:

我将样本存储在以下列表中

 sample = [AAAA,CGCG,TTTT,AT-T,CATC]

..为了说明问题,我在下面将它们表示为“集合”

Set1 AAAA
Set2 CGCG
Set3 TTTT
Set4 AT-T
Set5 CATC
    消除所有集合,其中集合中的每个元素都与其自身相同。

输出:

 Set2 CGCG
 Set4 AT-T
 Set5 CATC

    在集合之间执行成对比较。 (Set2 v Set4, Set 2v Set5, Set4 v Set5)

    每个成对比较只能有两种类型的组合,如果没有,则这些成对比较被消除。例如,

    Set2    Set5
    C       C
    G       A
    C       T 
    G       C
    

这里,对(CC),(GA),(CT)和(GC)有两种以上的类型。所以这种成对比较是不可能发生的。

每个比较只能有(AA,GG,CC,TT,AT,TA,AC,CA,AG,GA,GC,CG,GT,TG,CT,TC)中的2种组合......基本上都是顺序很重要的 ACGT 的可能组合。

在给定的示例中,找到了超过 2 个这样的组合。

因此,Set2 和 Set4;不能考虑 Set4 和 Set5。因此剩下的唯一对是:

Output
Set2 CGCG
Set4 AT-T

    在这个成对比较中,删除任何带有“-”的元素及其在另一对中的对应元素

    Output    
    Set2 CGG
    Set4 ATT
    

    计算 Set2 和 Set4 中元素的频率。计算集合中类型对的出现频率(CA 和 GT 对)

    Output
    Set2 (C = 1/3, G = 2/3)
    Set4 (A = 1/3, T = 2/3)
    Pairs (CA = 1/3, GT = 2/3)
    

    计算对应元素的float(a) = (Pairs) - (Set2) * (Set4)(任意一对就足够了)

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

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

    计算

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

    对所有成对比较重复此操作

例如。

Set2 CGCG
Set4 AT-T
Set6 GCGC

Set2 v Set4,Set2 v Set6,Set4 v Set6

到目前为止我的半生不熟的代码: ** 如果建议的所有代码都采用标准 for 循环格式而不是推导式,我会更喜欢 **

#Step 1
for i in sample: 
    for j in range(i):
        if j = j+1    #This needs to be corrected to if all elements in i identical to each other i.e. if all "j's" are the same
                        del i 
    #insert line of code where sample1 = new sample with deletions as above

#Step 2
    for i,i+1 in enumerate(sample):
    #Step 3
    for j in range(i):
        for k in range (i+1):
        #insert line of code to say only two types of pairs can be included, if yes continue else skip
            #Step 4
            if j = "-" or k = "-":
                #Delete j/k and the corresponding element in the other pair
                #Step 5
                count_dict = 
                    square_dict = 
                for base in list(i):
                    if base in count_dict:
                            count_dict[base] += 1
                    else:
                            count_dict[base] = 1
                    for allele in count_dict:
                    freq = (count_dict[allele] / len(i)) #frequencies of individual alleles
                    #Calculate frequency of pairs 
                #Step 6
                No code yet

【问题讨论】:

我不明白第 3 步。 CGCGAT-T 如何产生这些对? 每次比较只能有 2 种组合 (AA, GG,CC,TT, AT,TA,AC,CA,AG,GA,GC,CG,GT,TG,CT,TC) ...基本上所有可能的 ACGT 组合,其中顺序很重要。在给定的示例中,找到了超过 2 个这样的组合。因此,Set2 和 Set4; Set4 和 Set5 不能考虑。 您能否提供一个示例,说明您在步骤中对 AAAC 和 CCCA 所说的“c 的频率”是什么意思?是 1/4 还是 1/2?也就是说,是单对还是两对碱基的频率? base1 应该是什么?考虑到它们没有匹配的字母,set2 和 set4 是如何匹配的? 我已更正“base1”声明。 Set2 和 Set4 被认为是匹配的,因为它们符合标准,它只有 2 个唯一的组合 CA 和 GT..而 Set2 v Set5 有 (CC)、(GA)、(CT) 和 (GC)(超过2 对独特的) 【参考方案1】:

我想这就是你想要的:

from collections import Counter

# Remove elements where all nucleobases are the same.
for index in range(len(sample) - 1, -1, -1):
    if sample[index][:1] * len(sample[index]) == sample[index]:
        del sample[index]

for indexA, setA in enumerate(sample):
    for indexB, setB in enumerate(sample):
        # Don't compare samples with themselves nor compare same pair twice.
        if indexA <= indexB:
            continue

        # Calculate number of unique pairs
        pair_count = Counter()
        for pair in zip(setA, setB):
            if '-' not in pair:
                pair_count[pair] += 1

        # Only analyse pairs of sets with 2 unique pairs.
        if len(pair_count) != 2:
            continue

        # Count individual bases.
        base_counter = Counter()
        for pair, count in pair_count.items():
            base_counter[pair[0]] += count
            base_counter[pair[1]] += count

        # Get the length of one of each item in the pair.
        sequence_length = sum(pair_count.values())

        # Convert counts to frequencies.
        base_freq = 
        for base, count in base_counter.items():
            base_freq[base] = count / float(sequence_length)

        # Examine a pair from the two unique pairs to calculate float_a.
        pair = list(pair_count)[0]
        float_a = (pair_count[pair] / float(sequence_length)) - base_freq[pair[0]] * base_freq[pair[1]]

        # Step 7!
        float_b = float_a / float(base_freq.get('A', 0) * base_freq.get('T', 0) * base_freq.get('C', 0) * base_freq.get('G', 0))

或者,更 Python 化(使用您不想要的列表/字典推导):

from collections import Counter

BASES = 'ATCG'

# Remove elements where all nucleobases are the same.
sample = [item for item in sample if item[:1] * len(item) != item]

for indexA, setA in enumerate(sample):
    for indexB, setB in enumerate(sample):
        # Don't compare samples with themselves nor compare same pair twice.
        if indexA <= indexB:
            continue

        # Calculate number of unique pairs
        relevant_pairs = [(elA, elB) for (elA, elB) in zip(setA, setB) if elA != '-' and elB != '-']
        pair_count = Counter(relevant_pairs)

        # Only analyse pairs of sets with 2 unique pairs.
        if len(pair_count) != 2:
            continue

        # setA and setB as tuples with pairs involving '-' removed.
        setA, setB = zip(*relevant_pairs)

        # Get the total for each base.
        seq_length = len(setA)

        # Convert counts to frequencies.
        base_freq = base : count / float(seq_length) for (base, count) in (Counter(setA) + Counter(setB)).items()

        # Examine a pair from the two unique pairs to calculate float_a.
        pair = list(pair_count)[0]
        float_a = (pair_count[pair] / float(seq_length)) - base_freq[pair[0]] * base_freq[pair[1]]

        # Step 7!
        denominator = 1
        for base in BASES:
            denominator *= base_freq.get(base, 0)

        float_b = float_a / denominator

【讨论】:

在 # Remove elements where all nucleobases are the same, 你假设样品将具有相同的结构,只有 4 个碱基。它可以有 n 个碱基。我认为在示例中添加这个 sample1 = [] for i 会更好: if len(set(i)) > 1: sample1.append(i) (2) 很抱歉给您造成混淆,但是关于您之前的问题,当有 AAAC 和 CCCA 时,应该是 1/4,即频率超过一对。 另外,我在编译 float_b = float_a / (base_freq.get('A', 0) * base_freq.get('T', 0) * base_freq.get('C' , 0) * base_freq.get('G', 0)) ZeroDivisionError: 整数除以零或取模 评论 1:我很确定我是对的 - 如果整个字符串由第一个字符组成(如果存在 - 代码适用于零长度字符串),请删除它。 评论#3:我有这个作为sample的初始化器:sample = ['AAAA', 'CGCG', 'TTTT', 'AT-T', 'CATC']。也许你有不同的想法?

以上是关于如何计算Python中列表成对比较的元素频率?的主要内容,如果未能解决你的问题,请参考以下文章

如何计算无序列表中元素的频率?

二维列表中的Python计数元素频率[重复]

在python中,如何按元素的频率对列表进行排序

Python-列表元素出现次数及频率

Python 4.7:如何计算数组中特定值的频率[重复]

如何绘制列中单个元素的频率?