我有两个矩阵。一个的大小为 (CxK),另一个的大小为 (SxK)(其中 S、C 和 K 都有可能非常大)。我想使用余弦相似度函数(大小为 [CxS])将这些输出矩阵组合起来。当我运行代码时,需要很长时间才能产生输出,我想知道是否有任何方法可以优化我当前拥有的内容。 [注意,两个输入矩阵通常非常稀疏]
我之前使用两个 for index,row
循环遍历每个矩阵,但后来我切换到 while 循环,这显着提高了我的运行时间。
A #this is one of my input matrices (pandas dataframe)
B #this is my second input matrix (pandas dataframe)
C = pd.DataFrame(columns = ['col_1' ,'col_2' ,'col_3'])
i=0
k=0
while i <= 5:
col_1 = A.iloc[i].get('label_A')
while k < 5:
col_2 = B.iloc[k].get('label_B')
propensity = cosine_similarity([A.drop('label_A', axis=1)\
.iloc[i]], [B.drop('label_B',axis=1).iloc[k]])
d = {'col_1':[col_1], 'col_2':[col_2], 'col_3':[propensity[0][0]]}
to_append = pd.DataFrame(data=d)
C = C.append(to_append)
k += 1
k = 0
i += 1
现在我的循环只对每个矩阵中的 5 个项目运行,生成一个 5x5 矩阵,但我显然希望它适用于非常大的输入。这是我第一次做这样的事情,所以请让我知道代码的任何方面是否可以改进(用于保存矩阵的数据类型、如何遍历它们、更新输出矩阵等)。
提前谢谢您。
最佳答案
将标签移动到索引后,通过将整个数组传递给cosine_similarity
,可以更轻松、更快地完成此操作:
import pandas as pd
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
import time
c = 50
s = 50
k = 100
A = pd.DataFrame( np.random.rand(c,k))
B = pd.DataFrame( np.random.rand(s,k))
A['label_A'] = [f'A{i}' for i in range(c)]
B['label_B'] = [f'B{i}' for i in range(s)]
C = pd.DataFrame()
# your program
start = time.time()
i=0
k=0
while i < c:
col_1 = A.iloc[i].get('label_A')
while k < s:
col_2 = B.iloc[k].get('label_B')
propensity = cosine_similarity([A.drop('label_A', axis=1)\
.iloc[i]], [B.drop('label_B',axis=1).iloc[k]])
d = {'col_1':[col_1], 'col_2':[col_2], 'col_3':[propensity[0][0]]}
to_append = pd.DataFrame(data=d)
C = C.append(to_append)
k += 1
k = 0
i += 1
print(f'elementwise: {time.time() - start:7.3f} s')
# my solution
start = time.time()
A = A.set_index('label_A')
B = B.set_index('label_B')
C1 = pd.DataFrame(cosine_similarity(A, B), index=A.index, columns=B.index).stack().rename('col_3')
C1.index.rename(['col_1','col_2'], inplace=True)
C1 = C1.reset_index()
print(f'whole array: {time.time() - start:7.3f} s')
# verification
assert(C[['col_1','col_2']].to_numpy()==C1[['col_1','col_2']].to_numpy()).all()\
and np.allclose(C.col_3.to_numpy(), C1.col_3.to_numpy())
关于python - 优化矩阵遍历/通用代码优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57420245/