Python高效重采样

2024-09-30 16:20:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我想对序列重新采样,如下所示:

fastadict = {"seq1" : "ATGCAGTCACGT", "seq2" : "ATGTGTGTACG"}

我写了以下函数:

^{pr2}$

对于示例中的小序列来说,这很好。在我的工作中,我需要对大约100万个字母(DNA碱基,ACTG)取样10000次。此函数对此太慢。有没有一种更快的方法用python替换来获取采样?在


Tags: 方法函数示例字母序列dna碱基seq2
3条回答

使用numpy.random模块,该模块提供矢量化采样和视图转换:

>>> n, k = 20, 10
>>> 
>>> np.random.choice((*fastadict['seq1'],), replace=True, size=(n * k,)).view(f'U{k}')
array(['GCAGAATGCT', 'GGAGGTGCAT', 'CACCATCATT', 'CGTGGTGTAC',
       'AGAATATCGG', 'GATTTTGGCC', 'GAACATAAGC', 'CGGGCCAAGC',
       'GTTGGTGTTT', 'GACCAATAAC', 'ACCCGTAGCC', 'GAATTCCCGG',
       'AACAGGTCAC', 'AGACAAGCAC', 'CACACTTGCC', 'CGTTTGTAAT',
       'CTAGCCCTCG', 'CTCGACATAT', 'GATGATTAGA', 'TCTATCCTCA'],
      dtype='<U10')

Python 2版本:

^{pr2}$

速度:

>>> from time import perf_counter
>>> n, k = 100, 1000000
>>> t0 = perf_counter(); x = np.random.choice((*fastadict['seq1'],), replace=True, size=(n * k,)).view(f'U{k}');t1 = perf_counter()
>>> t1-t0
1.29188625497045

我比较了使用random.choice的版本与使用random.uniform的另一个版本。后者更快。后者根据字符串的长度生成随机数重新采样,并将其作为字符串的索引。在

这里有两个要比较的函数:您的resampling_f和{}。在


import random
import time

fastadict = {"seq1" : "ATGCAGTCACGT", "seq2" : "ATGTGTGTACG"};

def resampling_f(fastadict, seq, num): 
    fastadict[seq] = fastadict[seq].replace("N","").replace("n","") 
    l = [] 
    new_seq = ''.join([random.choice(fastadict[seq]) for i in range(num)]) 
    l.append(new_seq) 
    return l

def resample_new(data, num):
    new= ''.join([data[int(random.uniform(0,num))] for i in range(num)]);
    return new

与其在循环内fastadict[seq].replace....,不如在循环外执行,这样只需执行一次。在


下面是比较它们的代码:

^{pr2}$

我得到了total_13.6秒,total_2是{}秒。在

如果20万次重采样,我得到第一个37秒,第二个是28秒。在

我怀疑它慢的原因是每次你调用random_choice时,它都会覆盖整个系列。相反,您可以在一个系列中设置一个范围,计算每个项目出现的次数,然后从该分布中取样,例如使用numpy.random.choice。在

相关问题 更多 >