避免嵌套循环或列表推导



我正在使用亲和传播算法,我想从头开始编写它,而不使用scikit-learn。我用嵌套的for循环或列表理解编写了责任和可用性矩阵,但每个矩阵的执行时间都超过30分钟,数据超过2000人。

from scipy.spatial.distance import euclidean, pdist, squareform
import numpy as np
import pandas as pd
def similarity_func(u, v):
return -euclidean(u,v)
csv_data = pd.read_csv("DadosC.csv", delimiter=",", encoding="utf8", engine="python")
X = csv_data[{"InicialL", "FinalL"}].to_numpy().copy()
dists = pdist(X, similarity_func)    
distM = np.array(squareform(dists)) 
np.fill_diagonal(distM, np.median(distM))  
distM
A = np.zeros((X.shape[0],X.shape[0]))
def Respo(A,S,i,j):
a_0 = np.delete(A[i],j)                  
s_0 = np.delete(S[i],j)                   
return S[i][j]-max(a_0+s_0)
Lis = [[Respo(A,distM,i,j) for i in range(X.shape[0])] for j in range(X.shape[0])]
Res = np.reshape(Lis,(X.shape[0],X.shape[0])).T

这就是我所拥有的,A和S是2000x2000数组,A被初始化为null,但随后用类似的函数更新。当X是一个2000x2数组时,计算时间太长。你还能想到别的选择吗?

SciKit-Learn是一个围绕c库的包装器,它通常允许多线程和更快的执行速度。它也有许多内置的优化…

如果你想与SciKit-Learn的速度竞争,你可能需要用C而不是Python来编码。

Python在设计时并没有考虑到执行性能,绝大多数SciKit都是高度成熟的C模块的包装器。虽然其意图令人钦佩,但我还是建议您更加熟悉这个库在将python数据类型转换为C等效类型的上下文中是如何工作的。

为了与库的速度竞争,你首先要了解它们是如何调用和组织数据结构的,然后你必须尝试和改进它们,这不是不可能的,但根据FAQ页面的引用,这是极不可能的:

我们只考虑成熟的算法。经验法则是发表至少3年,被引用200次以上,被广泛使用和有用。在广泛使用的方法上提供明显改进的技术(例如,增强的数据结构或更有效的近似技术)也将被考虑纳入。

您可以尝试使用内置的map函数,如果您发布了"A"one_answers"distM",我将能够进一步演示,但请随意查看该函数。https://docs.python.org/3/library/functions.html#map通常,当使用ever map时,首选它,因为python中的循环没有那么快。

最新更新