我有一个字符串/叙述列表,我需要比较并获得每个字符串之间的距离度量。我编写的当前代码可以工作,但是对于较大的列表,它需要花费时间,因为我使用2 for循环。我用levenshtien距离来测量弦之间的距离。
字符串/叙述列表存储在数据框中。
def edit_distance(s1, s2):
m=len(s1)+1
n=len(s2)+1
tbl = {}
for i in range(m): tbl[i,0]=i
for j in range(n): tbl[0,j]=j
for i in range(1, m):
for j in range(1, n):
cost = 0 if s1[i-1] == s2[j-1] else 1
tbl[i,j] = min(tbl[i, j-1]+1, tbl[i-1, j]+1, tbl[i-1, j-1]+cost)
return tbl[i,j]
def narrative_feature_extraction(df):
startTime = time.time()
leven_matrix = np.zeros((len(df['Narrative']),len(df['Narrative'])))
for i in range(len(df['Narrative'])):
for j in range(len(df['Narrative'])):
leven_matrix[i][j] = edit_distance(df['Narrative'].iloc[i],df['Narrative'].iloc[j])
endTime = time.time()
total = (endTime - startTime)
print "Feature Extraction (Leven) Runtime:" + str(total)
return leven_matrix
X = narrative_feature_extraction(df)
如果列表有n个叙述,则生成的X是nxn矩阵,其中行是叙述,列是叙述的比较。例如,对于距离(i,j),它是叙述i和j之间的距离。
有没有办法优化此代码,以便不需要有这么多的for循环?或者有一种pythonic计算方法吗?
答案 0 :(得分:1)
很难在没有数据/示例的情况下提供确切的代码,但有一些建议:
实例/定时:
response = client.post('/models', data=json.dumps(job), headers=headers)
输出:
def test1(): #list comprehension
X=np.random.normal(size=(100,2))
results=[[x*y for x in X[:,0]] for y in X[:,1]]
df=pd.DataFrame(data=np.array(results))
if __name__ == '__main__':
import timeit
print("test1: "+str(timeit.timeit("test1()", setup="from __main__ import test1",number=10)))
def test2(): #enumerate, df at end
X=np.random.normal(size=(100,2))
results=np.zeros((100,100))
for ind,i in enumerate(X[:,0]):
for col,j in enumerate(X[:,1]):
results[ind,col]=i*j
df=pd.DataFrame(data=results)
if __name__ == '__main__':
import timeit
print("test2: "+str(timeit.timeit("test2()", setup="from __main__ import test2",number=10)))
def test3(): #in range, but df at end
X=np.random.normal(size=(100,2))
results=np.zeros((100,100))
for i in range(len(X)):
for j in range(len(X)):
results[i,j]=X[i,0]*X[j,1]
df=pd.DataFrame(data=results)
if __name__ == '__main__':
import timeit
print("test3: "+str(timeit.timeit("test3()", setup="from __main__ import test3",number=10)))
def test4(): #current method
X=np.random.normal(size=(100,2))
df=pd.DataFrame(data=np.zeros((100,100)))
for i in range(len(X)):
for j in range(len(X)):
df[i][j]=(X[i,0]*X[j,1])
if __name__ == '__main__':
import timeit
print("test4: "+str(timeit.timeit("test4()", setup="from __main__ import test4",number=10)))
因此列表理解速度提高约250倍,枚举速度是"对于范围内的x"速度的两倍。虽然真正的减速是你的数据帧的单独索引(即使使用.loc或.iloc,这仍然是你的瓶颈,所以我建议在可能的情况下使用df之外的数组)
希望这会有所帮助,您可以申请。我建议您阅读地图,过滤,缩小(可能是枚举)功能以及它们非常快速并且可以帮助您:http://book.pythontips.com/en/latest/map_filter.html
不幸的是,我对您的用例并不熟悉,但我不明白为什么它不适用于这种类型的代码调整或与之兼容。