Python 嵌套枚举,用于循环到理解列表
我正在使用Python 嵌套枚举,用于循环到理解列表,python,performance,list-comprehension,nested-loops,Python,Performance,List Comprehension,Nested Loops,我正在使用textdestance.neederman\u wunsch.normalized\u distance中的textdestance库()。我将它与Scipy库中的cdist一起使用,以计算序列的成对距离。但由于嵌套枚举for循环,该过程非常长 在这里您可以找到textdestance库中使用的代码,这需要时间,我想知道您是否知道如何加快嵌套for循环的速度,可能是使用列表理解 s1 = "sentence1" s2 = "sentevfers2&quo
textdestance.neederman\u wunsch.normalized\u distance
中的textdestance
库()。我将它与Scipy
库中的cdist
一起使用,以计算序列的成对距离。但由于嵌套枚举for循环,该过程非常长
在这里您可以找到textdestance
库中使用的代码,这需要时间,我想知道您是否知道如何加快嵌套for循环的速度,可能是使用列表理解
s1 = "sentence1"
s2 = "sentevfers2"
gap = 1
def sim_func(*elements):
"""Return True if all sequences are equal.
"""
try:
# for hashable elements
return len(set(elements)) == 1
except TypeError:
# for unhashable elements
for e1, e2 in zip(elements, elements[1:]):
if e1 != e2:
return False
return True
dist_mat = numpy.zeros(
(len(s1) + 1, len(s2) + 1),
dtype=numpy.float,
)
# DP initialization
for i in range(len(s1) + 1):
dist_mat[i, 0] = -(i * gap)
# DP initialization
for j in range(len(s2) + 1):
dist_mat[0, j] = -(j * gap)
""" Possible enhancement with list comprehension ? """
# Needleman-Wunsch DP calculation
for i, c1 in enumerate(s1, 1):
for j, c2 in enumerate(s2, 1):
match = dist_mat[i - 1, j - 1] + sim_func(c1, c2)
delete = dist_mat[i - 1, j] - gap
insert = dist_mat[i, j - 1] - gap
dist_mat[i, j] = max(match, delete, insert)
distance = dist_mat[dist_mat.shape[0] - 1, dist_mat.shape[1] - 1]
print(distance)
由于以下几个原因,此代码运行缓慢:
- 它(可能)用CPython执行,并用纯Python编写,这是一个速度很慢的解释器,不是为这种数字代码设计的李>
是一种比较各种元素的通用方法,但也非常低效(分配、哈希、异常处理和字符串操作)sim_func
s1=“句子1”
s2=“sentevfers2”
gap=1#假设这是一个整数
@njit
def NeedlemanWunschDP(距离垫,s1,s2):
对于范围(1,len(s1)+1)内的i:
对于范围(1,len(s2)+1)内的j:
match=dist_mat[i-1,j-1]+(s1[i-1]==s2[j-1])
删除=dist_mat[i-1,j]-间隙
插入=距离垫[i,j-1]-间隙
dist_mat[i,j]=最大值(匹配、删除、插入)
dist_mat=numpy.empty(
(len(s1)+1,len(s2)+1),
dtype=numpy.int64,
)
#DP初始化
对于范围内的i(len(s1)+1):
距离材料[i,0]=-(i*间隙)
#DP初始化
对于范围内的j(len(s2)+1):
距离垫[0,j]=-(j*间隙)
#将字符串转换为快速整数数组
tmp_s1=numpy.array([ord(e)表示s1中的e],dtype=numpy.int64)
tmp_s2=numpy.array([ord(e)表示s2中的e],dtype=numpy.int64)
#Needleman-Wunsch DP计算
NeedlemanWunschDP(距离垫、tmp垫s1、tmp垫s2)
距离=距离垫[距离垫形状[0]-1,距离垫形状[1]-1]
打印(距离)
在我的机器上编译
needermanwunschdp
大约需要400毫秒,但在大字符串上生成的代码要快1800倍以上。嵌套循环不会累积第三个列表,因此理解并不适合直接翻译。您可以使用理解来创建匹配
,删除
,插入
三元组的列表,然后迭代这些元组,但我看不出这是更好的。