我有这个函数来模拟 DNA 序列上的突变(例如字母序列 -> 'ACGTGCTTAGG')。
第一个只是改变输入序列的随机位置
def mutate(sequence):
seq_lst = list(sequence)
i = random.randint(0, len(seq_lst) - 1)
seq_lst[i] = random.choice(list('ATCG'))
return ''.join(seq_lst)
第二个是模拟在序列中的随机位置插入碱基。
def insertion(sequence):
seq_lst = list(sequence)
i = random.randint(0, len(seq_lst) - 1)
mutate = seq_lst[:i] + [random.choice(list('ATCG'))] + seq_lst[i:]
return ''.join(mutate)]
最后一个是选择序列中可能发生的各种可能的随机突变。
def mutations(sequence):
i = random.randint(0, 3)
print(i)
if i == 0:
print('SNV')
return mutate(sequence)
elif i == 1:
print('Del')
return sequence.replace(random.choice('ATCG'), '-')
elif i == 2:
print('Ins')
return insertion(sequence)
elif i == 3:
print('No mut')
return sequence
打印语句只是为了检查代码是否正常工作。
有什么改进建议吗?如果可能的话,建议如何在代码中插入突变概率以模拟更真实的情况。
我在返回10000个随机过程中看到的是,序列积累了大量的删除,这是错误的,一旦单点突变比较频繁,然后插入和删除的频率就比较少。
谢谢
最佳答案
因此序列模拟中会出现过多的缺失,
import random
sequence = 'ACTCAG'
sequence.replace(random.choice('ATCG'), '-')
出局
A-T-AG
对于给定事件,大约 1/4 的时间会同时发生两次删除。因此,概率并不均匀,导致删除的可能性比插入(或突变)的可能性更高。因此,插入或删除的可能性为 1/4,双删除的可能性为 1/4,而插入更改的可能性为 0。
还有另外两个偏见, 您将生成回复突变 A->A,因此 1/4 的突变不会出现突变。这自然会发生在 DNA 突变中,但值得注意。
最后,一旦发生删除,剩余核苷酸的突变就会增加,本质上您将使系统偏向于越来越少的核苷酸,因此剩余的核苷酸将经历增加的突变。
换句话说,概率不是均匀的,并且在模拟过程中是动态的。
您可以通过下面的函数使用 re.sub 以确保插入和删除之间的概率保持一致,
import random, re
def rand_replacement(string, to_be_replaced, items):
return re.sub(to_be_replaced, lambda x: random.choice(items), string )
关于python - 改进一些片段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57940773/