Форум сайта python.su
1
Здравствуйте.
Обучаюсь на on-line-курсе биоинформатики.
Задача следующая:
Frequent Words with Mismatches Problem: Find the most frequent k-mers with mismatches in a string.
Input: A string Text as well as integers k and d. (You may assume k ≤ 12 and d ≤ 3.)
Дано: Текст генома, целые k и d.
Output: All most frequent k-mers with up to d mismatches in Text.
Необходимо найти: Все самые распространённые k-мерные Куски(Образцы) в Тексте,
допускается не более d несовпадений.
———————
Моя программа:
""" Алгоритм решения (версия 2): Идём по Тексту и рубим Куски длиной k. Формируем Хэш-Словарь. Ключ - это числовой(бинарный) эквивалент Куска. Величина - это список. По индексу 0 там собственно строка-Кусок, по индексу 1 там список позиций вхождения Куска в Текст с допускаемыми d вариациями. Создаём список, содержащий под-списки. По индексу 0 в под-списке строка. Под-списков столько, что они охватывают по одному экземпляру все возможные варианты строк длиной k. По индексу 1 в под-списке будет под-под-список позиций. Затем обрабатывается уже этот словарь - ищется самый длинный список-Величина, или списки с равным максимальным количеством вхождений. Выводим на печать строки по индексу 0 в этих списках - это и будет ответ. """ TEXT_STRING = "ACGTTGCATGTCGCATGATGCATGAGAGCT" """ Геномный Текст для поиска. """ TEXT_STRING_LENGTH = len(TEXT_STRING) """ Длина Текста. """ PATTERN_STRING_LENGTH = 4 """ Длина Образца, то есть k-размерность. """ VALUE_OF_VARIABILITY = 1 """ Допустимое значение Изменчивости при поиске. """ primary_hash_dictionary = {} """ Наш Хэш-Словарь """ exit_list = [] """ Список для выходных данных """ # all_variants_k_mer_list = [] four_digit = [] def main_function_for_k_mer_text_and_mismatch(some_text): global primary_hash_dictionary, help_list_for_primary_hash_dictionary_processing for i in range(0, (TEXT_STRING_LENGTH - PATTERN_STRING_LENGTH + 1)): pattern_some = some_text[i : PATTERN_STRING_LENGTH + i] converted_some = "" key_some = 0 for f in range(PATTERN_STRING_LENGTH): if pattern_some[f] == "A": converted_some += "00" elif pattern_some[f] == "C": converted_some += "01" elif pattern_some[f] == "G": converted_some += "10" elif pattern_some[f] == "T": converted_some += "11" """ Преобразовываем строку текущего Куска в "бинарный" Ключ Хэш-Словаря. """ converted_some = "0b" + converted_some key_some = int(converted_some, 2) """ Если в словаре уже есть такой Ключ, то только добавляем новое значение позиции в список позиций. Если такого Ключа нет, то делаем первичное заполнение Хэш-Словаря. """ if primary_hash_dictionary.has_key(key_some): temp_list_1 = primary_hash_dictionary[key_some] temp_list_2 = temp_list_1[1] temp_list_2.append(i) temp_list_1[1] = temp_list_2 primary_hash_dictionary[key_some] = temp_list_1 else: primary_hash_dictionary[key_some] = [pattern_some, [i]] """ Теперь создаём список all_variants_k_mer_list с под-списками (а в них под-под-списки). Так как алфавит генома всего 4 символа, то мы создаём список four_digit содержащий в соответствующей позиции степень четвёрки. Потом каждое генерируемое число total_index мы разлагаем на степени 4 по модулю и в каждый разряд записываем соответственно символы A - там где 0, C - там где разряд при делении показал 1, G - 2, и T - 3. """ def all_variants_k_mer_list_function_creating_and_now_processing(): # global all_variants_k_mer_list global four_digit global primary_hash_dictionary, exit_list max_number_of_position = 1 for digit_fours in range(PATTERN_STRING_LENGTH): four_digit.append(4 ** digit_fours) # print four_digit for total_index in range(PATTERN_STRING_LENGTH ** 4): some_string = "" for digit_in_string in range(PATTERN_STRING_LENGTH - 1, -1, -1): quasi_digit = total_index // (four_digit[digit_in_string]) total_index = total_index % (four_digit[digit_in_string]) if quasi_digit == 0: digit_symbol = "A" some_string = some_string + digit_symbol elif quasi_digit == 1: digit_symbol = "C" some_string = some_string + digit_symbol elif quasi_digit == 2: digit_symbol = "G" some_string = some_string + digit_symbol elif quasi_digit == 3: digit_symbol = "T" some_string = some_string + digit_symbol temp_list_1 = [] # print some_string for key in primary_hash_dictionary: temp_list_2 = primary_hash_dictionary[key] pattern_some = temp_list_2[0] position_list_2 = temp_list_2[1] # print "pattern_some = ", pattern_some, "", position_list_2 index_of_pattern_some = 0 for m in range(PATTERN_STRING_LENGTH): if some_string[m] != pattern_some[m]: index_of_pattern_some += 1 if index_of_pattern_some == (VALUE_OF_VARIABILITY + 1): break if index_of_pattern_some <= VALUE_OF_VARIABILITY: temp_list_1 = temp_list_1 + position_list_2 # print temp_list_1 # print "" if len(temp_list_1) == max_number_of_position: exit_list.append(some_string) elif len(temp_list_1) > max_number_of_position: max_number_of_position = len(temp_list_1) exit_list = [some_string] # all_variants_k_mer_list.append([some_string, temp_list_1]) print "" print " ".join(exit_list) print max_number_of_position main_function_for_k_mer_text_and_mismatch(TEXT_STRING) all_variants_k_mer_list_function_creating_and_now_processing()
some_string = "" for digit_in_string in range(PATTERN_STRING_LENGTH - 1, -1, -1): quasi_digit = total_index // (four_digit[digit_in_string]) total_index = total_index % (four_digit[digit_in_string]) if quasi_digit == 0: digit_symbol = "A" some_string = digit_symbol + some_string elif quasi_digit == 1: digit_symbol = "C" some_string = digit_symbol + some_string elif quasi_digit == 2: digit_symbol = "G" some_string = digit_symbol + some_string elif quasi_digit == 3: digit_symbol = "T" some_string = digit_symbol + some_string
Отредактировано Kustodiev_17 (Дек. 25, 2013 17:36:41)
Офлайн
75
А где это такие курсы есть?
Офлайн
1
Здравствуйте, Singularity.
Есть на Курсере: https://www.coursera.org/
Офлайн
1
Коллеги, прошу меня простить - ошибка возникала из-за моей невнимательности - и все данные для ея поиска у меня имелись. Дело в том, что в цикле:
for total_index in range(PATTERN_STRING_LENGTH ** 4):
for total_index in range(4 ** PATTERN_STRING_LENGTH):
Офлайн
1
Здравствуйте.
Последняя часть моего последнего поста была, пожалуй, слишком оптимистичной. “Усушил” код исходя из своих новичковских представлений, а он выполняется за такое же время. Да, и работаю я сейчас на копьютере-ветеране: для сравнения запустил программму, которая работала с геномом бактерии - получилось, что нынешний мой комп в два раза медленнее (сработал за 01 минуту и 09 секунд вместо 39 секунд).
Мои мысли:
1) У Лутца “Изучаем Питон” указана инфа про ускорители типа Psyco и транслятор Shedskin - однако у меня нет опыта работы с этим хозяйством. Как подступиться и насколько это быстро даст результаты (время освоения и применения - хотелось бы в течение недели уложиться).
2) Скорее всего узкое место моей программы - генерация всех возможных строк от “AAA…AA” до “TT….TTT” - если у кого есть опыт как это сделать с меньшими временнЫми затратами - буду признателен и буду за вас молится всем компьютерным БогАм как минимум до 01.01.2015. 
По поводу “узкого места” у меня есть такой план “реализации своими силами” - сгенерить заранее файлы (три штуки) со строками в вариантах длины 8, 9 и 10 символов (это то, что в моей программе величина PATTERN_STRING_LENGTH). И в зависимости от полученного задания программа будет целиком считывать весь объём данных без генерации, обращаясь к соответствующему файлу, либо, если PATTERN_STRING_LENGTH < 8, то генерить напрямую.
В самом худшем случае, который пока встречается PATTERN_STRING_LENGTH = 10, то есть всех возможных комбинаций 4 ** 10 = 2 ** 20 = (2 ** 10) ** 2 = (1024) ** 2 примерно 1 000 000 или 10 ** 6. Соответственно размер файла со строками = (примерно) 10М. Мой ветеран возможно будет переваривать столько же (буду пробовать в любом случае, так как нужен опыт по работе с файлами - пока он минимален - бактериальный геном считывать получается, а вот поиск/запись, тем более структурированная - пока мне не известна).
Всем удачи.
Отредактировано Kustodiev_17 (Дек. 26, 2013 16:19:06)
Офлайн
43
Kustodiev_17
генерация всех возможных строк от “AAA…AA” до “TT….TTT”
In [19]: from itertools import product In [20]: for c in product('ACGT',repeat=2): ...: print(''.join(c)) ...: AA AC AG AT CA CC CG CT GA GC GG GT TA TC TG TT
Kustodiev_17не надо
у меня есть такой план …
так медленней будет
Офлайн
1
Да, нужно именно получать строки заданной длинны (теоретически до 12 символов, а практически до 10 символов). То есть, если PATTERN_STRING_LENGTH = 9, то по моему алгоритму нужно получить все строки -
AAAAAAAAA
AAAAAAAAC
AAAAAAAAG
AAAAAAAAT
AAAAAAACA
AAAAAAACC
……
TTTTTTTTG
TTTTTTTTT
К моему сожалению синтаксис
In [20]:
product('ACGT',repeat=2)
Отредактировано Kustodiev_17 (Дек. 26, 2013 17:58:35)
Офлайн
43
Kustodiev_17это приглашение к вводу в ipython, тоже самое чтоIn [20]:
>>>
Kustodiev_17это функция из модуля itertools - считает декартово произведение, в параметр len вводится число ваших символов, например для 12product('ACGT',repeat=2)
from itertools import product for c in product('ACGT',repeat=12): print(''.join(c))
Офлайн
1
Спасибо, sergeek. Сейчас осваиваю новый материал. Думаю, что вопросов быть не должно. Благодарю ещё раз.
Офлайн
43
Kustodiev_17я привел пример с выводом для лучшего понимания
единственное не понял пока как эти все значения присваивать строковой переменной (мне на печать вывод без надобности).
from itertools import product for c in product('ACGT',repeat=12): var = ''.join(c)
Офлайн