【问题标题】:Efficient finding of string mismatches in large lists有效查找大型列表中的字符串不匹配
【发布时间】:2013-11-10 22:26:01
【问题描述】:

我正在遍历大量字符串以查找相似的字符串(有几个不匹配)。以下代码有效,但需要约 20 分钟,而我的目标是在 5 分钟内完成。有没有更有效的方法来做到这一点?这段代码的哪一部分限制最大?

我有k=10mism=3seq 是一个由字符 A、T、C 和 G 组成的字符串。每个 patternkmer 都是 k 个字符长。 我生成了长度为 4**k(~100 万)的patterns 和长度为 len(seq)-k+1(~300)的kmers 列表。 frequent 是一本字典。

测试迭代不到一分钟:

for i in range (0,4**k):
    for j in range(0,len(kmers)):
        pass

为了提高效率,我需要进行真正的计算:

for pattern in patterns:
    for kmer in kmers:
        mism_counter=0
        for j in range(0,k):
            if not kmer[j]==pattern[j] : mism_counter+=1
        if mism_counter <= mism :
            if pattern in frequent:
                frequent[pattern] += 1
            else:
                frequent[pattern] = 1

我尝试了 wikipedia 的 hamming_distance 函数而不是我的每个字符比较,还尝试删除字典并将 pattern 转储到列表中以供进一步处理。这些都没有提高循环的性能。任何帮助将不胜感激!

【问题讨论】:

  • 你有第三个循环:for j in range(k);这使得每个外部循环增加了 10 个循环。 10 次“不到一分钟”仍然接近 10 分钟,加上 if 测试和字典访问。
  • @MartijnPieters 没有删除 for 循环将时间从 O(n^3) 减少到 O(n^2)?
  • @Dunno:第三次循环:k=10;第一个循环:4**k (~1e6)
  • 代码中的seq在哪里?
  • 另外,最后一个if可以移动到第一个循环(for kmer完成后)吗?

标签: python string performance comparison


【解决方案1】:

这应该节省一半的时间;-)

for pattern in patterns:
    for kmer in kmers:
        mism_counter=0
        for j in range(0,k):
            if kmer[j] != pattern[j] : 
                mism_counter+=1
                if mism_counter > misn:
                    break
        else:
            if pattern in frequent:
                frequent[pattern] += 1
            else:
                frequent[pattern] = 1

你必须做两件事才能让它变得非常快:

  • 压缩数据以减少程序的工作量。您不必将 GTAC 表示为 ascii 字母(每个 7 位),而是每个字母 2 位就足够了。
  • 从模式中构建搜索尝试以加快比较速度。您对允许不匹配的搜索基本上会炸毁您拥有的模式数量。您可以使用额外的边进行尝试,从而允许出现许多不匹配,但这实际上会使您的搜索集变得庞大。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-12
    • 1970-01-01
    • 2019-07-21
    相关资源
    最近更新 更多