【发布时间】:2013-11-01 10:40:39
【问题描述】:
我有大量包含序列('ATCGTGTGCATCAGTTTCGA...')的记录,最多 500 个字符。我还有一个较小序列的列表,通常是 10-20 个字符。我想使用 Levenshtein 距离来在记录中找到这些较小的序列,从而允许小的变化或插入缺失 (L_distance
问题是我也想得到这么小的序列的起始位置,显然它只比较相同长度的序列。
>>> import Levenshtein
>>> s1 = raw_input('first word: ')
first word: ATCGTAATACGATCGTACGACATCGCGGCCCTAGC
>>> s2 = raw_input('second word: ')
first word: TACGAT
>>> Levenshtein.distance(s1,s2)
29
在本例中,我想获取位置 (7) 和距离(在本例中为 0)。
有没有一种简单的方法可以解决这个问题,还是我必须将较大的序列分解成较小的序列,然后对所有序列运行 Levenshtein 距离?这可能需要太多时间。
谢谢。
UPDATE #Naive 实现在查找完全匹配后生成所有子字符串。
def find_tag(pattern,text,errors):
m = len(pattern)
i=0
min_distance=errors+1
while i<=len(text)-m:
distance = Levenshtein.distance(text[i:i+m],pattern)
print text[i:i+m],distance #to see all matches.
if distance<=errors:
if distance<min_distance:
match=[i,distance]
min_distance=distance
i+=1
return match
#Real example. In this case just looking for one pattern, but we have about 50.
import re, Levenshtein
text = 'GACTAGCACTGTAGGGATAACAATTTCACACAGGTGGACAATTACATTGAAAATCACAGATTGGTCACACACACATTGGACATACATAGAAACACACACACATACATTAGATACGAACATAGAAACACACATTAGACGCGTACATAGACACAAACACATTGACAGGCAGTTCAGATGATGACGCCCGACTGATACTCGCGTAGTCGTGGGAGGCAAGGCACACAGGGGATAGG' #Example of a record
pattern = 'TGCACTGTAGGGATAACAAT' #distance 1
errors = 2 #max errors allowed
match = re.search(pattern,text)
if match:
print [match.start(),0] #First we look for exact match
else:
find_tag(pattern,text,errors)
【问题讨论】:
-
我已经读过那篇文章,但那里没有完全回答。你如何获得这个职位?正如我在原始问题中指出的那样,这只是创建子字符串。
-
get_matching_blocks 文档说:返回描述匹配子序列的三元组列表。每个三元组的形式为 (i, j, n),表示 a[i:i+n] == b[j:j+n]。三元组在 i 和 j 中单调递增。 这不会给你位置吗?
-
您需要这样才能提高效率吗?只是迭代每个序列的子字符串并计算 L 距离会太慢吗?
-
我仍然不知道如何从该单行中提取位置。是的,我需要一个高效的代码,因为我有数百万条记录,并且要查找的可能子字符串约为 50-60。
标签: python algorithm levenshtein-distance dna-sequence