刚刚学python,想写一个关于文本内容比对的代码,这是从文本中摘取的几列内容
#Sequence Barcode Count Percentage(%)
AAGAGTGTATGTAGGGAGGA barcodeMD-AS-17MD-S-50 73974821 1.240810
GGTGGAAGGGGGAGGTGGTG barcodeMD-AS-21MD-S-61 73670799 1.235710
GGTGGAAGGGCTAGGGAGCA barcodeMD-AS-21MD-S-50 73627661 1.234987
GGAGTTATGGCTGAGTGGTT ambiguous 22315579 0.374308
我需要比对的ambiguous这一行的Sequence和其他列的Sequence中不同的碱基,如果超过3个碱基不同,就将他舍弃,如果是三个碱基以下则将其写入文本文件中,并输出一共有多少有个碱基差异小于3个序列。
现在代码写完了,但是我嵌套了三个循环导致代码运行速度很慢,有办法可以提高他跑的速度呢?
目前我采用的方法是,一条序列中的元素与另一条序列中的元素,一一对应进行比较,还有别的方法可以达到这样的效果吗?
allcount = 0 #定义一个计数器
for w in range(0,listAmbiguousLen): #我将所有的ambiguous列添加到了一个列表中,listAmbiguousLen 指的是ambiguous一共有多少行
for u in range(0,lenSeq): #Seq是整个文本,lenSeq指的是这个文本一共有多少行
count = 0 # 定义一个计数器
uncount = 0
for x in range(0,lenAmbiguous): # lenAmbiguous 指的是Sequence列中,碱基的个数,一般为20个
if listAmbiguous[w][x] == Seq[u][x]: #如果first的元素与list的元素相同
count = count + 1
else: # 如果不相同
uncount = uncount+1
if uncount>3: # 如果碱基不同的个数大于3个,则舍弃
break
elif count > lenAmbiguous-number: #如果碱基小于三个,就把他写入文档中
allcount = allcount + 1 #allcount+1
l.write(str(uncount)+"\t"+listAmbiguous[w]+"\t\t"+Seq[u])
break
import Levenshtein
a = 'GGAGTTATGGCTGAGTGGTT'
b = 'GGTGGAAGGGCTAGGGAGCA'
res = Levenshtein.hamming(a, b)
print(res)
--result
10
你的代码中嵌套了三层循环,所以运行速度很慢。你可以尝试使用以下方法来优化你的代码:
1、减少循环的次数:可以尝试使用某些函数来减少循环的次数,比如使用zip()函数可以同时遍历两个列表的元素。
2、使用更快的数据结构:你可以使用更快的数据结构,比如字典或集合来替换列表。
3、使用 numpy:你可以使用 numpy 来快速进行数学运算,而不是使用循环。
4、使用多线程/多进程:如果你的代码可以被分解成多个独立的任务,你可以使用多线程或多进程来提高运行速度。
我将使用zip()函数来同时遍历ambiguous序列和Seq序列中的元素,这样就可以减少一层循环。然后,将使用字典来记录每个序列中碱基不同的个数,这样就不需要使用第三层循环来遍历每一个碱基了。
这是优化后的代码:
allcount = 0 # 定义一个计数器
result = {} # 定义一个字典用于记录每个序列中碱基不同的个数
for w in range(0, listAmbiguousLen): # 遍历ambiguous序列
for u, seq in enumerate(Seq): # 遍历Seq序列
count = sum(a != b for a, b in zip(listAmbiguous[w], seq)) # 计算碱基不同的个数
if count <= 3: # 如果碱基不同的个数小于等于3个,则写入文档中
allcount = allcount + 1 # allcount+1
result[u] = count
l.write(str(count)+"\t"+listAmbiguous[w]+"\t\t"+seq)
print(f'一共有{len(result)}个碱基差异小于3个序列')
比对时,可以使用 Python 的字符串方法来加速解决。
如果 seq1 和 seq2 都是字符串,可以使用 Python 的字符串方法 difflib.ndiff 来比较两个字符串的差异。这个方法会返回一个生成器,生成器中的每一项都是一个三元组,表示两个字符串中对应位置的字符是否相同。
下面是一个示例代码:
import difflib
# seq1 和 seq2 是字符串
diff = difflib.ndiff(seq1, seq2)
# 计算两个字符串的不同字符数
num_differences = 0
for item in diff:
if item[0] != ' ':
num_differences += 1
if num_differences > 3:
# 两个字符串有超过 3 个不同的字符
# ...
ChatGPT尝试为您解答,仅供参考
这个问题的瓶颈在于比较每一个碱基的差异,这需要三重循环进行比较。如果你的文本很大,那么比较的次数就会很多,导致程序运行较慢。
为了提高运行速度,你可以尝试以下几种方法。
用python的difflib比较
import difflib
def similar_diff_qk_ratio(str1, str2):
return difflib.SequenceMatcher(None, str1, str2).quick_ratio()
# 最好保持长度一致, 方便比较, 如果长度不一致, 请参考SequenceMatcher用法
str1 = 'GGG'
str2 = 'GAG'
ratio = similar_diff_qk_ratio(str1, str2)
print('相同率:', ratio)
print('不同的元素个数:', (1 - ratio) * len(str1))
打印结果:
相同率: 0.6666666666666666
不同的元素个数: 1.0