【问题标题】:Generating random sequences of DNA生成随机的 DNA 序列
【发布时间】:2021-06-28 23:57:22
【问题描述】:

我正在尝试使用随机数和随机字符串在 python 中生成随机 DNA 序列。但我只得到一个字符串作为我的输出。例如:如果我给出长度为 5 (String(5)) 的 DNA,我应该得到一个输出“CTGAT”。同样,如果我给 String(4) 它应该给我“CTGT”。但我得到的是“G”或“C”或“T”或“A”;即每次只有一个字符串。有人可以帮我吗?

我尝试了以下代码:

from random import choice
def String(length):

   DNA=""
   for count in range(length):
      DNA+=choice("CGTA")
      return DNA

【问题讨论】:

    标签: python dna-sequence


    【解决方案1】:

    我会一次性生成所有字符串,而不是构建它。除非 Python 很聪明并优化了字符串添加,否则它将把运行时复杂度从二次降低到线性。

    import random
    
    def DNA(length):
        return ''.join(random.choice('CGTA') for _ in xrange(length))
    
    print DNA(5)
    

    【讨论】:

    • 投反对票的人应该留个便条(例如“问题是关于理解代码块和缩进”)。使用str.join() 比逐个添加字母(DNA 碱基)要快得多。
    • 代替 random.choice('CGTA') 您可以将每个碱基的频率降低,如下所示: random.choice("A"*5+"C"*4+"G" *3+“T”*10)。将我给出的数字替换为您需要使用的真实相对数字。
    【解决方案2】:

    你回来太快了:

    from random import choice
    def String(length):
    
       DNA=""
       for count in range(length):
          DNA+=choice("CGTA")
          return DNA
    

    如果您的 return 语句在 for 循环内,您将只迭代一次 --- 您将退出带有 return 的函数。

    来自Python Documentation on return statements: "return 离开当前函数调用,并将表达式列表(或 None)作为返回值。"

    所以,将return 放在函数的末尾:

    def String(length):
    
           DNA=""
           for count in range(length):
              DNA+=choice("CGTA")
           return DNA
    

    编辑:这是一种加权选择方法(它目前仅适用于字符串,因为它使用字符串重复)。

    def weightedchoice(items): # this doesn't require the numbers to add up to 100
        return choice("".join(x * y for x, y in items))
    

    然后,您想在循环中调用 weightedchoice 而不是 choice

    DNA+=weightedchoice([("C", 10], ("G", 20), ("A", 40"), ("T", 30)])

    【讨论】:

    • 非常感谢。它现在正在工作。我可以添加一个分布,它是一个元组列表,例如 String(10,[("a",20),("b",60),("c",20)]) 其中概率总和为 100( 20+60+20)
    【解决方案3】:

    我已升级代码以提供从 0 到 100% 的 GC 百分比分布。上面的代码总是产生 50% 的分布。

    actg_distribution 字符串可以是已知 GC 百分比的现有 DNA 序列的任意长度。某个范围的 GC 百分比是一个常见的用例。

    
    import random
    
    # Return random CGTA sequences, set minimum = maximum to get a specified length.
    def random_length_dnasequence(minimum=25, maximum=10000, actg_distribution=None):
        if (minimum == maximum):
            length = minimum
        else:
            length = random.randint(minimum, maximum)
        if (actg_distribution == None):
            actg_distribution = ''.join(random.choice('cgta') for _x in xrange(7))
    
        return ''.join(random.choice(actg_distribution) for _x in xrange(length))
    
    
    def random_dnasequence(length, actg_distribution=None):
        return random_length_dnasequence(length, length, actg_distribution)
    

    【讨论】:

      【解决方案4】:

      使用 random.choices 的 python 3.6 快速函数

      import random
      
      def string(length=int(), letters="CGTA"):
              #slower 0.05s for 20000 nt
      #     dna =""
      #     for count in range(length):
      #         dna+=choice("CGTA")
      #     return dna
      
          #0.013s for 20000 nt
          return''.join(random.choices(letters, k=length)
      

      【讨论】:

        【解决方案5】:

        也许由于矢量化,numpy 工作得更快?:

        import numpy as np
        seq_length = 100
        my_seq = ''.join(np.random.choice(('C','G','T','A'), seq_length ))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多