Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 嵌套枚举,用于循环到理解列表_Python_Performance_List Comprehension_Nested Loops - Fatal编程技术网

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
    是一种比较各种元素的通用方法,但也非常低效(分配、哈希、异常处理和字符串操作)
代码不容易并行化,因此无法矢量化numpy。但是,您可以使用Numba来加快速度。只有当输入字符串相当大或此处理需要执行很多时间时,才值得这样做。如果不是这种情况,请使用更合适的编程语言(如C、C++、D、RISE等)或专用的Python模块。 以下是优化的Numba代码:

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倍以上。

嵌套循环不会累积第三个列表,因此理解并不适合直接翻译。您可以使用理解来创建
匹配
删除
插入
三元组的列表,然后迭代这些元组,但我看不出这是更好的。