2015-12-14 2 views
5

Я хотел бы создать одну горячую кодировку для набора последовательностей ДНК. Например, последовательность ACGTCCA может быть представлена ​​ниже в транспонированном виде. Но приведенный ниже код будет генерировать одну горячую кодировку горизонтальным способом, в котором я бы предпочел ее в вертикальной форме. Может кто-нибудь мне помочь?Как генерировать одну горячую кодировку для последовательностей ДНК?

ACGTCCA 
1000001 - A 
0100110 - C 
0010000 - G 
0001000 - T 

Пример кода:

from sklearn.preprocessing import OneHotEncoder 
import itertools 

# two example sequences 
seqs = ["ACGTCCA","CGGATTG"] 


# split sequences to tokens 
tokens_seqs = [seq.split("\\") for seq in seqs] 

# convert list of of token-lists to one flat list of tokens 
# and then create a dictionary that maps word to id of word, 
# like {A: 1, B: 2} here 
all_tokens = itertools.chain.from_iterable(tokens_seqs) 
word_to_id = {token: idx for idx, token in enumerate(set(all_tokens))} 

# convert token lists to token-id lists, e.g. [[1, 2], [2, 2]] here 
token_ids = [[word_to_id[token] for token in tokens_seq] for tokens_seq in tokens_seqs] 

# convert list of token-id lists to one-hot representation 
vec = OneHotEncoder(n_values=len(word_to_id)) 
X = vec.fit_transform(token_ids) 

print X.toarray() 

Однако код дает мне выход:

[[ 0. 1.] 
[ 1. 0.]] 

Ожидаемый результат:

[[1. 0. 0. 0. 0. 0. 1. 0. 1. 0. 0. 1. 1. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0.] 
[0. 0. 0. 1. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 1. 1. 0. 0. 0. 1. 0. 0. 0. 0. 1. 1. 0.]] 

ответ

4

Я предлагаю сделать это немного более ручной путь:

import numpy as np 

seqs = ["ACGTCCA","CGGATTG"] 

CHARS = 'ACGT' 
CHARS_COUNT = len(CHARS) 

maxlen = max(map(len, seqs)) 
res = np.zeros((len(seqs), CHARS_COUNT * maxlen), dtype=np.uint8) 

for si, seq in enumerate(seqs): 
    seqlen = len(seq) 
    arr = np.chararray((seqlen,), buffer=seq) 
    for ii, char in enumerate(CHARS): 
     res[si][ii*seqlen:(ii+1)*seqlen][arr == char] = 1 

print res 

Это дает желаемый результат:

[[1 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0] 
[0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 0]] 
+0

Спасибо. Это прекрасно решалось для одиночных оснований A, T, C, G. Могу ли я узнать, можно ли использовать на динуклеотиде, которые имеют 16 возможных комбинаций, таких как AA, AT, AC, AG и т. Д. Если он появился как TGA, тогда TG будет дано значение 1, а GA тоже задано значение 1. – Xiong89

+0

@ Xiong89: Я уверен, что вы можете заставить его работать, но если я собираюсь написать весь ваш код для вас, я могу задать почасовую ставку! Я думаю, что главный строительный блок, который вам нужен для случая di, таков: 'arr = np.chararray ((3, 2), buffer = 'asdfds')' then 'np.all (np.chararray ((2,), buffer = 'as') == arr, axis = 1) '- это дает вам массив' [True, False, False] '. То есть вам нужно собрать все 16 двухсимвольных комбо как 'chararray', а затем сопоставить их. Попробуйте. :) –

Смежные вопросы