我有大量包含序列('ATCGTGTGCATCAGTTTCGA...')的记录,最多 500 个字符。我还有一个较小序列的列表,通常是 10-20 个字符。我想使用 Levenshtein 距离来在记录中找到这些较小的序列,从而允许小的变化或插入缺失(L_distance <=2)。
问题是我也想得到这样更小的序列的起始位置,显然它只比较相同长度的序列。
>>> 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)