繁体   English   中英

比较字符串列表中字符串中每个字符的最快方法

[英]Fastest method to compare each character in string in a list of strings

我正在使用一个生物信息学工具,并使用两个循环来遍历每个字符来构建它。

输入(即 seq1 和序列)是一串核苷酸,例如相同长度的“ AGATGCTAGTA' sequence_info是所有sequence_info的列表。

它非常慢,所以我通过使用 continue 而不是添加零并将bio_array存储为 numpy 数组来提高速度。 这是新代码。

for (sequence, sequence_location) in sequence_info:
    value = slow_function(seq1, sequence)

def slow_function(seq1,sequence):
    calc=0
    for i,nt in enumerate(seq1):
        if nt == sequence[i]:
            continue
        else:
            calc += bio_array[i]
    return float(calc)

在 jupyter notebooks 中使用%%timeit它仍然在100ms左右。 我需要它在1-5ms左右或以下。 我尝试将函数转换为迭代器并使用列表推导式/映射而不是使用循环。 但这些方法没有显着影响。

我认为可能可以使用 numpy,但我无法通过查看文档或 stackoverflow 找到一种使用方法。 如果序列中存在不匹配,我需要将bio_array特定值加在一起,因此我需要单独比较字符串中的每个字符值,我认为。

将这段代码的速度提高到尽可能快的最佳方法是什么?

如果我理解正确,您的问题是您希望根据两个字符串序列不匹配的位置对数组的元素求和。 您可以简单地创建序列的字符数组,然后使用 numpy 条件索引来获取不匹配的值。 这是一个简化的示例:

seq_a = np.array(list('ABCDEFGH'))
seq_b = np.array(list('ABCZEFZH'))
bio_array = np.array([1, 5, 9, 4, 3, 8, 2, 7])

然后,在seq_aseq_b之间进行元素比较seq_b得到:

>>> seq_a != seq_b
array([False, False, False, True, False, False, True, False])

然后,您可以使用此结果索引bio_array以获取相关值,然后将它们相加:

>>> bio_array[seq_a != seq_b]
array([4, 2])

>>> bio_array[seq_a != seq_b].sum()
6

您应该接受@sshashank124 的回答,但这里有一些快速的代码来显示正在发生的事情以及它有多少不同:

import numpy as np
from timeit import timeit


def slow_function(seq1, seq2, costs):
    calc = 0
    for i, nt in enumerate(seq1):
        if nt == seq2[i]:
            continue
        else:
            calc += costs[i]
    return float(calc)


def shorter_slow_function(seq1, seq2, costs):
    return sum(costs[i] for i in range(len(seq1)) if seq1[i] != seq2[i])


def faster_numpy_function(seq1, seq2, costs):
    return costs[seq1 != seq2].sum()


x = np.array(list('ABCDE'))
y = np.array(list('XBCDY'))
c = np.array([1.0, 2.0, 3.0, 4.0, 5.0])


print(timeit(lambda: slow_function(x, y, c)))
print(timeit(lambda: shorter_slow_function(x, y, c)))
print(timeit(lambda: faster_numpy_function(x, y, c)))

结果:

6.7421024
6.665790399999999
5.321171700000001

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM