这是一个问题:用一个包含G元素的列表来表示G大小的基因组,其中每个元素都包含有关该位置的相关信息,例如,该位置的核苷酸被测序了多少次。若要模拟一次测序过程,请执行以下步骤:·将列表中的所有元素设置为0(标记每个核苷酸已被测序0次)。·随机选择L大小R读的起始位置,并对每次读更新所包含的核苷酸序列的次数进行测定。
到目前为止我有这样的想法:
genome = [0]*G
for x in range(R):
randlocation = random.randint(0,G-L)
genome = genome[0:randlocation] + [x+1 for x in genome[randlocation:(randlocation+L)]] + genome[(randlocation+L):]
print genome但是这对于G,R和L值来说太慢了,我们需要在(3000000,40000,500)上测试它。如果能帮助加快速度,我们将不胜感激。
发布于 2017-10-12 00:06:23
不要总是重新创建新的列表(列表切片创建副本),只需要在嵌套的for循环中增加每个元素:
genome = [0]*G
for x in range(R):
randlocation = random.randint(0,G-L)
for i in range(randlocation, randlocation+L):
genome[i] += 1
print genome使用numpy可能会更快..。因为您可以直接在片上使用矢量化操作:类似于genome[randlocation:randlocation+L] += 1的操作(但是在这里使用视图而不是副本)
发布于 2017-10-12 00:21:33
虽然Julien的答案在使用RAM方面是有效的,但是在普通Python中有一种更快的方法。使用列表理解来执行添加,并使用切片分配将结果复制回基因组。
import random
# Seed the randomizer so we can get consistent timings
random.seed(42)
G, R, L = 3000000, 40000, 500
genome = [0] * G
for x in range(R):
loc = random.randint(0, G-L)
genome[loc:loc + L] = [x+1 for x in genome[loc:loc + L]]在我的旧的2 2GHz 32位机器上运行Python3.6,大约需要7±0.5秒。相反,使用此循环执行更新。
for x in range(R):
loc = random.randint(0, G-L)
for i in range(loc, loc + L):
genome[i] += 1大约需要18±0.5秒。但是它确实使用了更多的内存,因为它需要在每个循环中创建一个L大小的列表。当然,Python会回收用于这些列表的内存,而且由于L只有500,所以这种内存的使用不值得担心。
FWIW,如果我们使用Numpy实现这一点,我们可以将时间减少到2秒或更短。另一个好处是Numpy数组使用本机数据类型(在本例中为机器整数),因此RAM开销小于使用Python对象列表。
import numpy as np
import random
# Seed the randomizer so we can get consistent timings
random.seed(42)
G, R, L = 3000000, 40000, 500
genome = np.zeros(G, dtype=np.int)
for x in range(R):
loc = random.randint(0, G-L)
genome[loc:loc + L] += 1我不是Numpy专家,所以可能有更有效的方法来做这件事。
https://stackoverflow.com/questions/46699307
复制相似问题