【问题标题】:Python edit distancePython编辑距离
【发布时间】:2012-07-12 20:13:11
【问题描述】:

我是一名分子生物学家,使用 Biopython 分析基因突变,我的问题是:

我有一个包含许多不同序列(数百万)的文件,其中大部分是重复的。我需要找到重复项并丢弃它们,为每个唯一序列保留一份副本。我打算使用模块 editdist 来计算它们之间的编辑距离,以确定哪些是重复项,但 editdist 只能处理 2 个字符串,而不是文件。

任何人都知道我可以如何将该模块与文件而不是字符串一起使用?

【问题讨论】:

  • 读入文件并将其拆分成单词然后比较单词?
  • 你能发布一些关于文件包含的更多信息吗?每一行都是一个序列吗?是否有诸如“BEGIN SEQUENCE”或“END SEQUENCE”之类的标记? ?
  • 您是对近似重复(editdist 可能有用)还是实际重复感兴趣?
  • 我对分子生物学了解不多,但基本上,您拥有的是一个字符串列表(序列?),并且您希望它们是唯一的(没有两个字符串是相同的) , 对?如果是这样,也许 Python 中的 set (docs.python.org/library/stdtypes.html#set) 类型可以帮助您!正如 Russel 在我之前所说的那样,这只有在您正在寻找完全相同的重复项时才有效。
  • 文件包含序列和序列ID。没有标记,只是不同序列之间的换行符

标签: python sequence edit distance biopython


【解决方案1】:

假设您的文件仅由每行排列一个序列的序列组成,我建议如下:

seq_file = open(#your file)

sequences = [seq for seq in seq_file]

uniques = list(set(sequences))

假设你有它的记忆。几百万?

预计到达时间:

正在阅读上面的 cmets(但没有评论权限) - 假设任何重复项的序列 ID 相同,这将起作用。如果重复的序列可以有不同的序列ID,那么就知道文件中哪个先出现,它们之间是什么。

【讨论】:

    【解决方案2】:

    如果要过滤掉完全重复的内容,可以使用set Python 内置类型。举个例子:

    a = ["tccggatcc", "actcctgct", "tccggatcc"] # You have a list of sequences
    s = set(a) # Put that into a set
    

    s 等于 ['tccggatcc', 'actcctgct'],没有重复。

    【讨论】:

    • 可能,是的。这是一个简单、不费吹灰之力的解决方案,但它会起作用。你还有什么想法吗?
    • 如果“大部分”是重复的,也许在解析文件时将它们用作字典键,如for sequence in lot_of_sequences: dict.setdefault(sequence) 将消耗更少的内存。
    • 如果您可以流式传输您的值(而不是在一个大列表中一次读取它们),您可以使用迭代器,并且使用的内存只会随着唯一项目的数量而增长。即使项目数量非常非常大,这也应该有效。
    【解决方案3】:

    必须是 Python 吗?

    如果序列只是每行一个的文本字符串,那么 shell 脚本将非常有效:

    sort input-file-name | uniq > output-file-name
    

    这将在 32 位 Linux 上处理高达 2GB 的文件。

    如果您使用的是 Windows,请安装 GNU utils http://gnuwin32.sourceforge.net/summary.html

    【讨论】:

      【解决方案4】:

      想到四件事:

      1. 您可以使用 set(),如 F.X. 所述。 - 假设唯一 字符串都适合内存
      2. 您可以为每个序列使用一个文件,并将这些文件提供给程序 像equivs3e: http://stromberg.dnsalias.org/~strombrg/equivalence-classes.html#python-3e
      3. 您也许可以使用 gdbm 作为一个集合,而不是通常的 键值存储使用。如果您需要 100% 的东西,这很好 准确,但是您有太多数据无法容纳所有唯一性 虚拟内存。
      4. 您也许可以使用布隆过滤器将数据减少到更多 可管理的大小,如果你有大量的字符串 检查和很多重复。基本上布隆过滤器可以说 “这绝对不在系列中”或“这几乎肯定在 集”。这样,你可以消除大部分明显的 在使用更常见的方法对 剩余元素。 http://stromberg.dnsalias.org/~strombrg/drs-bloom-filter/

      【讨论】:

        【解决方案5】:

        不要害怕文件! ;-)

        我通过假设以下内容发布示例:

        1. 它是一个文本文件
        2. 每行一个序列

        -

        filename = 'sequence.txt'
        with open(filename, 'r') as sqfile:
           sequences = sqfile.readlines() # now we have a list of strings
        
        #discarding the duplicates:
        uniques = list(set(sequences))
        

        就是这样 - 通过使用 pythons set-type 我们自动消除所有重复。

        如果你在同一行中有 id 和序列,例如:

        423401 ttacguactg
        

        您可能希望消除以下 id:

        sequences = [s.strip().split()[-1] for s in sequences]
        

        使用 strip 我们从前导和尾随空格中去除字符串,使用 split 我们将行/字符串分成 2 个组件:id 和序列。 使用 [-1] 我们选择最后一个组件(= 序列字符串)并将其重新打包到我们的序列列表中。

        【讨论】: