Поиск подстроки с наибольшим количеством повторений в словаре с последовательностями днк - PullRequest
0 голосов
/ 17 апреля 2020

Подстрока должна состоять из 6 символов. Число, которое я получаю, меньше, чем должно быть.

Сначала я написал код для получения последовательностей из файла, затем поместил их в словарь, затем написал 3 вложенных цикла: первая итерация по словарю и получает последовательность в каждой итерации. Второй берет каждую последовательность и получает из нее подстроку из 6 символов. В каждой итерации вторая l oop увеличивает индекс начала строки (длинной последовательности) на 1. Третья l oop берет каждую подстроку из второй l oop и считает, сколько раз она появляется в каждой строке (длинная последовательность).

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

Я добавил файл с 3 сокращенными последовательностями для тестирования. Возможно, попробуйте меньшую подстроку: скажем, с 3 символами вместо 6: rep_len = 3

Код

matches = []
count = 0
final_count = 0
rep_len = 6
repeat = ''
pos  = 0
seq_count = 0
seqs = {}
f = open(r"file.fasta")
# inserting each sequences from the file into a dictionary
for line in f:
    line = line.rstrip()
    if line[0] == '>':
        seq_count += 1
        name = seq_count
        seqs[name] = ''
    else:
        seqs[name] += line
for key, seq in seqs.items():  # getting one sequence in each iteration
    for pos in range(len(seq)):  # setting an index and increasing it by 1 in each iteration
        if pos <= len(seq) - rep_len: # checking no substring from the end of the sequence are selected
            repeat = seq[pos:pos + rep_len] # setting a substring
            if repeat not in matches: # checking if the substring was already scanned
                matches.append(repeat) # adding the substring to previously checked substrings' list
                for key1, seq2 in seqs.items(): # iterating over each sequence
                    count += seq2.count(repeat) # counting the substring's repetitions
                if count > final_count: # if the count is greater than the previously saved greatest number
                    final_count = count # the new value is saved
                count = 0    
print('repetitions: ', final_count) # printing

sequence.fasta

Ответы [ 2 ]

1 голос
/ 17 апреля 2020

Код не очень понятен, поэтому его немного сложно отладить. Я предлагаю переписать.

Во всяком случае, я (в настоящее время) только что заметил одну маленькую ошибку:

        if pos < len(seq) - rep_len:

Должно быть

        if pos <= len(seq) - rep_len:

В настоящее время последний символ в каждой последовательности игнорируется.

РЕДАКТИРОВАТЬ:

Вот несколько переписать ваш код, который является более понятным и может помочь вам исследовать ошибки:

rep_len = 6
seq_count = 0
seqs = {}
filename = "dna2.txt"

# Extract the data into a dictionary
with open(filename, "r") as f:
    for line in f:
        line = line.rstrip()
        if line[0] == '>':
            seq_count += 1
            name = seq_count
            seqs[name] = ''
        else:
            seqs[name] += line

# Store all the information, so that you can reuse it later
counter = {}

for key, seq in seqs.items():
    for pos in range(len(seq)-rep_len):
        repeat = seq[pos:pos + rep_len]
        if repeat in counter:
            counter[repeat] += 1
        else:
            counter[repeat] = 1

# Sort the counter to have max occurrences first
sorted_counter = sorted(counter.items(), key = lambda item:item[1], reverse=True  )

# Display the 5 max occurrences
for i in range(5):
    key, rep = sorted_counter[i]
    print("{} -> {}".format(key, rep))

# GCGCGC -> 11
# CCGCCG -> 11
# CGCCGA -> 10
# CGCGCG -> 9
# CGTCGA -> 9

0 голосов
/ 17 апреля 2020

Возможно, будет проще использовать Counter из модуля collections в Python. Также ознакомьтесь с библиотекой NLTK.

Пример:

from collections import Counter
from nltk.util import ngrams

sequence = "cggttgcaatgagcgtcttgcacggaccgtcatgtaagaccgctacgcttcgatcaacgctattacgcaagccaccgaatgcccggctcgtcccaacctg"

def reps(substr): 
    "Counts repeats in a substring"
    return sum([i for i in Counter(substr).values() if i>1])


def make_grams(sent, n=6):
    "splits a sentence into n-grams"
    return ["".join(seq) for seq in (ngrams(sent,n))]

grams = make_grams(sequence) # splits string into substrings
max_length = max(list(map(reps, grams))) # gets maximum repeat count

result = [dna for dna in grams if reps(dna) == max_length]
print(result)

Вывод: ['gcgtct', 'cacgga', 'acggac', 'tgtaag', 'agaccg', 'gcttcg', 'cgcaag', 'gcaagc', 'gcccgg', 'cccggc', 'gctcgt', 'cccaac', 'ccaacc']

И если вопрос заключается в поиске строки с наиболее повторяющимся символом :

repeat_count = [max(Counter(a).values()) for a in result] # highest character repeat count
result_dict = {dna:ct for (dna,ct) in zip(result, repeat_count)}

another_result = [dna for dna in result_dict.keys() if result_dict[dna] == max(repeat_count)]
print(another_result)

Вывод: ['cccggc', 'cccaac', 'ccaacc']

...