我目前正在处理一些DNA序列数据,我需要为每个站点创建一个频率矩阵。例如,像这样:
A T G C
0.2 0.3 0.3 0.2
0.3 0.4 0.1 0.2
0.7 0.1 0.1 0.1
输入是许多DNA序列的列表,例如:
te_seqs = ["ATCTACTGATG", "ATACAGTACATAGA", "ATAGACAGTTGTGCG", "GTCGATACGT", ...]
每个序列长达数千个字符,并且有数千个序列。输出是一个numpy矩阵,包含每个站点的频率计数。例如,在上面的数据中,第一个站点有3个As和1个G,因此A的频率是3/4 = 0.75,G的频率是1/4 = 0.25。 T和C的频率都是0。
我目前有一个包含所有序列的列表,我通过在Nx4矩阵中加1来获得频率。问题是我正在使用大量的序列,并且嵌套for循环并不是理想的时间:
for seq in te_seqs:
for i,nuc in enumerate(seq):
if nuc == "A":
te_pwm[i, 0] = te_pwm[i, 0] + 1
elif nuc == "T":
te_pwm[i, 1] = te_pwm[i, 1] + 1
elif nuc == "G":
te_pwm[i, 2] = te_pwm[i, 2] + 1
elif nuc == "C":
te_pwm[i, 3] = te_pwm[i, 3] + 1
for seq in gene_seqs:
for i,nuc in enumerate(seq):
if nuc == "A":
gene_pwm[i, 0] = gene_pwm[i, 0] + 1
elif nuc == "T":
gene_pwm[i, 1] = gene_pwm[i, 1] + 1
elif nuc == "G":
gene_pwm[i, 2] = gene_pwm[i, 2] + 1
elif nuc == "C":
gene_pwm[i, 3] = gene_pwm[i, 3] + 1
我的问题是1)是否有一种更加pythonic的方法来检查蜇伤列表中的每个字符串? 2)有没有更好的方法来创建基频矩阵?
谢谢!
答案 0 :(得分:4)
您可以使用itertools.izip_longest()
迭代网站,然后使用collections.Counter
进行计数:
import collections
import itertools
te_seqs = ["ATCTACTGATG", "ATACAGTACATAGA", "ATAGACAGTTGTGCG", "GTCGATACGT"]
sites = map(collections.Counter, itertools.izip_longest(*te_seqs))
for site in sites:
A = site.get("A", 0)
T = site.get("T", 0)
G = site.get("G", 0)
C = site.get("C", 0)
total = float(A + T + G + C)
print A / total, T / total, G / total, C / total
这会产生
0.75 0.0 0.25 0.0
0.0 1.0 0.0 0.0
0.5 0.0 0.0 0.5
0.0 0.25 0.5 0.25
1.0 0.0 0.0 0.0
0.0 0.25 0.25 0.5
0.5 0.5 0.0 0.0
...