Python 中序列/字符串之间的突变/不匹配计数

问题描述 投票:0回答:1

我有数百万个蛋白质序列来比较并输出总突变计数。序列已对齐,但包含“-”和“X”,正如猜测的那样,我不想计算这些字母。我为此尝试了基本的 python 编码,但这看起来相当慢。 有没有最快的方法?

例如-

seq1='GYPX-AM'
seq2='GNPXXCM'

这些应该返回突变值 2。

当序列位于列表中时,我尝试了 python zip 函数和基本 for 循环。我还尝试了

Levenshtein
距离模块来实现此目的,速度更快,但我没有找到任何忽略或省略那些“-”和“X”的选项。

python string sequence levenshtein-distance mismatch
1个回答
0
投票

您可以使用 Numpy 来加快速度。首先:一个简单的循环实现。

# Here's a simple "normal loop" implementation.
# It's not very fast, but it seems to work.
def compare(a: str, b: str) -> int:
    if a in ("-", "X") or b in ("-", "X"):
        return 0
    
    if a == b:
        return 0
    
    return 1

def compare_proteins(a: str, b: str) -> int:
    score = 0
    for i in range(len(a)):
        score += compare(a[i], b[i])
    return score

在我的机器上比较两个 1000 万个字符串大约需要 8 秒。可能会更糟,但我们可以通过使用 Numpy 显着加快速度。

# This assumes 'proteins_a' and 'proteins_b' are arrays of strings,
# not strings
a = np.array(proteins_a)
b = np.array(proteins_b)


# We can ignore '-' and 'X' by setting them to the same value
mask = (a == '-') | (a == 'X') | (b == '-') | (b == 'X')
a[mask] = '-'
b[mask] = '-'

# Then we can count the total number of differences via np.sum.
# For a boolean array, True is 1 and False is 0, so this works
# and is very efficient.
diffs = np.sum(a!=b)

在我的测试中,Numpy 实现速度大约快 60 倍,处理 1000 万个字符大约需要 140 毫秒。您还可以使用 Numba 或 Cython,或者用 C 或 Rust 或其他语言编写自己的函数,从而使其速度更快。但如果您想要“正常工作”并且易于实现的东西,直接的 Numpy 可能是一个很好的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.