2014-11-06 3 views
1

Я пытался написать код, который нужно вывести как матрицу, но, будучи новичком, я не понимаю. В основном я хочу создать матрицу подсчетов для каждого из A, C, G, T для каждого столбца. Я смог сделать это для одного столбца, но мне было трудно сделать это для других столбцов.как заполнить матрицу в python

входного файла

>Rosalind_1 
ATCCAGCT 
>Rosalind_2 
GGGCAACT 
>Rosalind_3 
ATGGATCT 
>Rosalind_4 
AAGCAACC 
>Rosalind_5 
TTGGAACT 
>Rosalind_6 
ATGCCATT 
>Rosalind_7 
ATGGCACT 

Мой код до сих пор

fh_in = open("consensus_seq.txt", 'r') 

A_count = 0 
C_count = 0 
G_count = 0 
T_count = 0 

result = [] 
for line in fh_in: 
    line = line.strip() 
    if not line.startswith(">"): 
     for nuc in line[0]: 
      if nuc == "A": 
       A_count += 1 
      if nuc == "C": 
       C_count += 1 
      if nuc == "G": 
       G_count += 1 
      if nuc == "T": 
       T_count += 1 
result.append(A_count) 
result.append(C_count) 
result.append(G_count) 
result.append(T_count) 
print result 

Выход

[5, 0, 1, 1] 

Фактический выход, который я хочу

A 5 1 0 0 5 5 0 0 
C 0 0 1 4 2 0 6 1 
G 1 1 6 3 0 1 0 0 
T 1 5 0 0 0 1 1 6 

Любая помощь/подсказка оцениваются.

ответ

1

Вы можете использовать numpy, чтобы загрузить текстовый файл. Поскольку формат немного напуганный, трудно загрузить, но суммирование становится тривиальным после этого:

import numpy as np 
data = np.loadtxt("raw.txt", comments=">", 
        converters = {0: lambda s: [x for x in s]}, dtype=str) 

print (data=="A").sum(axis=0) 
print (data=="T").sum(axis=0) 
print (data=="C").sum(axis=0) 
print (data=="G").sum(axis=0) 

Выход:

[5 1 0 0 5 5 0 0] 
[1 5 0 0 0 1 1 6] 
[0 0 1 4 2 0 6 1] 
[1 1 6 3 0 1 0 0] 

Реальное преимущество это NumPy массив вы построили может делать другие вещи. Например, предположим, что я хотел бы знать, вместо суммы, среднее число раз мы нашли A вдоль колонны «Rosalinds»:

print (data=="A").mean(axis=0) 
[ 0.71428571 0.14285714 0. 0. 0.71428571 0.71428571 0. 0.] 
+0

Это так легко. Благодаря.... – upendra

1
import collections 
answer = [] 
with open('blah') as infile: 
    rows = [line.strip() for _,line in zip(infile, infile)] 
    cols = zip(*rows) 
    for col in cols: 
    d = collections.Counter(col) 
    answer.append([d[i] for i in "ATCG"]) 
    answer = [list(i) for i in zip(*answer)] 
for line in answer: 
    print(' '.join([str(i) for i in line])) 

Выход:

5 1 0 1 0 
0 0 1 6 6 
5 0 2 0 1 
0 1 6 0 0 
3

Сначала составьте список строк, зачистки строки, начиная с>. Тогда вы можете указать zip, чтобы превратить его в список столбцов. Затем вы можете составить список столбцов столбцов каждой буквы.

rows = [line.strip() for line in infile if not line.startswith('>')] 
columns = zip(*rows) 
for letter in 'ACGT': 
    print letter, [column.count(letter) for column in columns] 

Однако это может быть интенсивный объем памяти, если ваш файл очень большой. Альтернативой является просто пройти по строке, подсчитывая буквы.

counts = {letter: [0] * 8 for letter in 'ACGT'} 
for line in infile: 
    if not line.startswith('>'): 
     for i, letter in enumerate(line.strip()): 
      counts[letter][i] += 1 
for letter, columns in counts.items(): 
    print letter, columns 

Вы также можете использовать Counter, особенно если вы не уверены заранее, сколько колонок будет иметь:

from collections import Counter 
# ... 
counts = Counter() 
for line in infile: 
    if not line.startswith('>'): 
     counts.update(enumerate(line.strip())) 

columns = range(max(counts.keys())[0]) 
for letter in 'ACGT': 
    print letter, [counts[column, letter] for column in columns] 
+0

+1. Я знаю про zip, но расскажу мне об этом 'zip (* rows)', что * здесь представляет? – Hackaholic

+0

* распаковывает список аргументов https://docs.python.org/2/tutorial/controlflow.html#unpacking-argument-lists. В этом случае он отправляет первую строку в zip как первый аргумент, вторую строку как второй аргумент и т. Д. – Stuart

+0

что, если число столбцов не равно 8? Есть ли способ вставить функцию 'len' в список счетчиков? – upendra

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