python计算序列列表中是否存在子字符串的数量
你可以在这里得到数据! 底部下载 我正在用python分析生物数据 我写了一段代码,在长字符串列表中查找匹配的子字符串 子串在一个列表中,长度为7个核苷酸 因此在列表中,从AAAAAAA到TTTTTTT,共有16384个基序(子串),排列为A,C,G,T 这段代码有一个for循环,用于子字符串列表和嵌套在其中的长字符串列表 它工作正常,但由于列表有12000行,代码处理非常慢 换言之,提供AAAAA信息和下一个AAAAA C信息需要2分钟 因此,需要16384个图案才能通过12000行2分钟,这将需要(16384*2==32768分钟->546小时->22天…) 我使用scipy和numpy来获取Pvalues 我想要的是计算序列列表中是否存在子字符串的数量 长字符串列表和代码如下所示:python计算序列列表中是否存在子字符串的数量,python,string,numpy,scipy,bioinformatics,Python,String,Numpy,Scipy,Bioinformatics,你可以在这里得到数据! 底部下载 我正在用python分析生物数据 我写了一段代码,在长字符串列表中查找匹配的子字符串 子串在一个列表中,长度为7个核苷酸 因此在列表中,从AAAAAAA到TTTTTTT,共有16384个基序(子串),排列为A,C,G,T 这段代码有一个for循环,用于子字符串列表和嵌套在其中的长字符串列表 它工作正常,但由于列表有12000行,代码处理非常慢 换言之,提供AAAAA信息和下一个AAAAA C信息需要2分钟 因此,需要16384个图案才能通过12000行2分钟,这
list_of_lists_long = [
[BGN, -0.054, AGGCAGCTGCAGCCACCGCGGGGCCTCAGTGGGGGTCTCTGG....]
[ABCB7, 0.109, GTCACATAAGACATTTTCTTTTTTTGTTGTTTTGGACTACAT....]
[GPR143, -0.137, AGGGGATGTGCTGGGGGTCCAGACCCCATATTCCTCAGACTC....]
[PLP2, -0.535, GCGAACTTCCCTCATTTCTCTCTGCAATCTGCAAATAACTCC....]
[VSIG4, 0.13, AAATGCCCCATTAGGCCAGGATCTGCTGACATAATTGCCTAG....]
[CCNB3, -0.071, CAGCAGCCACAGGGCTAAGCATGCATGTTAACAGGATCGGGA....]
[TCEAL3, 0.189, TGCCTTTGGCCTTCCATTCTGATTTCTCTGATGAGAATACGA....]
....] #12000 lines
是否有更快的逻辑来加快代码的执行速度
我需要你的帮助
先谢谢你
=====================================
有没有更简单的方法,而不执行任何其他事情
我认为模式匹配的迭代是个问题
我想知道的是,一个长度为7的图案在整个序列列表中出现了多少次,而不是也出现了多少次!!!。所以,如果一个主题出现在一个字符串中,作为bool为真,那么增加一个值,然后增加一个值,然后增加一个值
不是字符串中的图案数量。好问题。这是一个经典的计算机科学问题。是的,确实有一个更好的算法。您的处理每个长字符串16384次。更好的方法是只处理每个长字符串一次 与其在每个长字符串中搜索每个基序,不如只记录每个长字符串中出现的基序。例如,如果在以下字符串中搜索长度为2的图案:
s = 'ACGTAC'
然后,您可以在长度为2的子字符串上运行一个循环,并记录在dict
中存在的子字符串:
motifAppearances = {}
for i in range(len(s)-1):
motif = s[i:i+2] # grab a length=2 substring
if motif not in motifAppearances:
motifAppearances[motif] = 0 # initialize the count
motifAppearances[motif] += 1 # increment the count
现在,您已经对整个字符串进行了一次精确处理,并找到了其中存在的所有图案。在这种情况下,生成的dict如下所示:
motifAppearances = {'AC':2, 'CG':1, 'GT':1, 'TA':1}
为您的案例执行类似的操作将使您的运行时间减少16384倍。您的代码有一些奇怪的地方
itertools.product
计算i[2].find(sMotif)<1
的比较将返回True
,如果字符串正好在开头,这似乎有点奇怪OddsRatio、PValue
和Enrichment
计算在循环内,但计数的归零和print
都不在循环内,这意味着您在为每一新行累积计算它们,但不使用该信息进行任何操作i[2]。查找(sMotif)
。该结果不会被缓存假设我理解你试图计算的数字——我很可能是错的,因为你在做一些我不理解的事情——我会颠倒逻辑。不要在每一个图案上循环,试着在每一行中数一数,而是在每一行上循环,看看有什么。这将是大约7行的数量,而不是图案的数量,行的数量 例如:
import random
from itertools import product
from collections import defaultdict, Counter
N = 12000
datalength = 400
listoflists = [[str(i), random.uniform(-1, 1),
''.join([random.choice('AGCT') for c in range(datalength)])]
for i in range(N)]
def chunk(seq, width):
for i in range(len(seq)-width+1):
yield seq[i:i+width]
def count_motifs(datatriples, width=7):
motif_counts_by_down = defaultdict(Counter)
nonmotif_counts_by_down = defaultdict(Counter)
all_motifs = set(''.join(p) for p in product('AGCT',repeat=width))
for symbol, value, sdata in datatriples:
down = value < -0.5
# what did we see?
motifs_seen = set(chunk(sdata, width))
# what didn't we see?
motifs_not_seen = all_motifs - motifs_seen
# accumulate these
motif_counts_by_down[down].update(motifs_seen)
nonmotif_counts_by_down[down].update(motifs_not_seen)
return motif_counts_by_down, nonmotif_counts_by_down
from sklearn.feature_extraction.text import CountVectorizer
def make_chunks(s):
width = 2
return [s[i:i+width] for i in range(len(s)-width+1)]
l = ['ATTGCGGCTCACGAA', 'ACCTAGATACGACGG', 'CCCCTGTCCATGGTA']
vectorizer = CountVectorizer(tokenizer=make_chunks)
X = vectorizer.fit_transform(l)
>>> X.sum(axis=0)
[[1 4 1 3 2 5 4 3 3 2 3 2 3 2 3 1]]
所以我估计整个问题大约需要20分钟,这对于这么少的代码来说并不坏。(我们可以通过做算术来加速motif\u-not\u-seen
部分,但这只会让我们得到2倍的速度。)
在更小的情况下,更容易看到输出:
>>> mot, nomot = count_motifs(listoflists, 2)
>>> mot
defaultdict(<class 'collections.Counter'>,
{False: Counter({'CG': 61, 'TC': 58, 'AT': 55, 'GT': 54, 'CA': 53, 'GA': 53, 'AC': 52, 'CT': 51, 'CC': 50, 'AG': 49, 'TA': 48, 'GC': 47, 'GG': 45, 'TG': 45, 'AA': 43, 'TT': 40}),
True: Counter({'CT': 27, 'GT': 26, 'TC': 24, 'GC': 23, 'TA': 23, 'AC': 22, 'AG': 21, 'TG': 21, 'CC': 19, 'CG': 19, 'CA': 19, 'GG': 18, 'TT': 17, 'GA': 17, 'AA': 16, 'AT': 16})})
>>> nomot
defaultdict(<class 'collections.Counter'>,
{False: Counter({'TT': 31, 'AA': 28, 'GG': 26, 'TG': 26, 'GC': 24, 'TA': 23, 'AG': 22, 'CC': 21, 'CT': 20, 'AC': 19, 'GA': 18, 'CA': 18, 'GT': 17, 'AT': 16, 'TC': 13, 'CG': 10}),
True: Counter({'AA': 13, 'AT': 13, 'GA': 12, 'TT': 12, 'GG': 11, 'CC': 10, 'CA': 10, 'CG': 10, 'AG': 8, 'TG': 8, 'AC': 7, 'GC': 6, 'TA': 6, 'TC': 5, 'GT': 3, 'CT': 2})})
>mot,nomot=count\u模体(列表,2)
>>>莫特
defaultdict(,
{False:Counter({'CG':61,'TC':58,'AT':55,'GT':54,'CA':53,'GA':53,'AC':52,'CT':51,'CC':50,'AG':49,'TA':48,'GC':47,'GG':45,'TG':45,'AA':43,'TT':40}),
对:计数器({'CT':27,'GT':26,'TC':24,'GC':23,'TA':23,'AC':22,'AG':21,'TG':21,'CC':19,'CG':19,'CA':19,'GG':18,'TT':17,'GA':17,'AA':16,'AT':16})
>>>诺莫
defaultdict(,
{False:Counter({'TT':31,'AA':28,'GG':26,'TG':26,'GC':24,'TA':23,'AG':22,'CC':21,'CT':20,'AC':19,'GA':18,'CA':18,'GT':17,'AT':16,'TC':13,'CG':10}),
正确:计数器({'AA':13,'AT':13,'GA':12,'TT':12,'GG':11,'CC':10,'CA':10,'CG':10,'AG':8,'TG':8,'AC':7,'GC':6,'TA':6,'TC':5,'GT':3,'CT':2})
基本上,您的问题是序列比较。寻找序列中的基序是生物信息学中的一个基本问题。我想你可以搜索一些现有的算法或软件包。我在谷歌搜索了关键词“motif match”,这是我在第一页找到的:
一种干净且非常快速的方法(OP的数据约为15秒)是使用of,因为它在引擎盖下使用numpy,例如:
import random
from itertools import product
from collections import defaultdict, Counter
N = 12000
datalength = 400
listoflists = [[str(i), random.uniform(-1, 1),
''.join([random.choice('AGCT') for c in range(datalength)])]
for i in range(N)]
def chunk(seq, width):
for i in range(len(seq)-width+1):
yield seq[i:i+width]
def count_motifs(datatriples, width=7):
motif_counts_by_down = defaultdict(Counter)
nonmotif_counts_by_down = defaultdict(Counter)
all_motifs = set(''.join(p) for p in product('AGCT',repeat=width))
for symbol, value, sdata in datatriples:
down = value < -0.5
# what did we see?
motifs_seen = set(chunk(sdata, width))
# what didn't we see?
motifs_not_seen = all_motifs - motifs_seen
# accumulate these
motif_counts_by_down[down].update(motifs_seen)
nonmotif_counts_by_down[down].update(motifs_not_seen)
return motif_counts_by_down, nonmotif_counts_by_down
from sklearn.feature_extraction.text import CountVectorizer
def make_chunks(s):
width = 2
return [s[i:i+width] for i in range(len(s)-width+1)]
l = ['ATTGCGGCTCACGAA', 'ACCTAGATACGACGG', 'CCCCTGTCCATGGTA']
vectorizer = CountVectorizer(tokenizer=make_chunks)
X = vectorizer.fit_transform(l)
>>> X.sum(axis=0)
[[1 4 1 3 2 5 4 3 3 2 3 2 3 2 3 1]]
现在,X
是一个稀疏矩阵,所有可能的块作为列,序列作为行,其中每个值是每个序列中给定块的出现次数:
>>> X.toarray()
# aa ac ag at ca cc cg ...
[[1 1 0 1 1 0 2 1 1 2 1 0 0 1 1 1] # ATTGCGGCTCACGAA
[0 3 1 1 0 1 2 1 2 0 1 0 2 0 0 0] # ACCTAGATACGACGG
[0 0 0 1 1 4 0 1 0 0 1 2 1 1 2 0]] # CCCCTGTCCATGGTA
>>> (X.toarray()>0).astype(int) # the same but counting only once per sequence
[[1 1 0 1 1 0 1 1 1 1 1 0 0 1 1 1]
[0 1 1 1 0 1 1 1 1 0 1 0 1 0 0 0]
[0 0 0 1 1 1 0 1 0 0 1 1 1 1 1 0]]
>>> vectorizer.get_feature_names() # the columns(chunks)
[u'aa', u'ac', u'ag', u'at', u'ca', u'cc', u'cg', u'ct', u'ga', u'gc', u'gg', u'gt', u'ta', u'tc', u'tg', u'tt']
现在,您可以沿列求和、屏蔽非值或需要执行的任何操作,例如:
import random
from itertools import product
from collections import defaultdict, Counter
N = 12000
datalength = 400
listoflists = [[str(i), random.uniform(-1, 1),
''.join([random.choice('AGCT') for c in range(datalength)])]
for i in range(N)]
def chunk(seq, width):
for i in range(len(seq)-width+1):
yield seq[i:i+width]
def count_motifs(datatriples, width=7):
motif_counts_by_down = defaultdict(Counter)
nonmotif_counts_by_down = defaultdict(Counter)
all_motifs = set(''.join(p) for p in product('AGCT',repeat=width))
for symbol, value, sdata in datatriples:
down = value < -0.5
# what did we see?
motifs_seen = set(chunk(sdata, width))
# what didn't we see?
motifs_not_seen = all_motifs - motifs_seen
# accumulate these
motif_counts_by_down[down].update(motifs_seen)
nonmotif_counts_by_down[down].update(motifs_not_seen)
return motif_counts_by_down, nonmotif_counts_by_down
from sklearn.feature_extraction.text import CountVectorizer
def make_chunks(s):
width = 2
return [s[i:i+width] for i in range(len(s)-width+1)]
l = ['ATTGCGGCTCACGAA', 'ACCTAGATACGACGG', 'CCCCTGTCCATGGTA']
vectorizer = CountVectorizer(tokenizer=make_chunks)
X = vectorizer.fit_transform(l)
>>> X.sum(axis=0)
[[1 4 1 3 2 5 4 3 3 2 3 2 3 2 3 1]]
最后,要找到给定主题的出现次数,必须找到相应主题/块的索引,然后在前面的总和中计算:
>>> index = vectorizer.vocabulary_.get('ag') # 'ag' is your motif
2 # this means third column
在您的情况下,您必须将列表分为两部分(正值和负值),以包括关闭条件。我用DSM的列表做了一个快速测试