是否可以将此Python代码转换为Cython?



我实际上希望尽可能加快这段代码的#2,所以我认为尝试Cython可能会很有用。但是,我不确定如何在 Cython 中实现稀疏矩阵。有人可以展示如何/是否可以将其包裹在 Cython 或 Julia 中以使其更快吗?

#1) This part computes u_dict dictionary filled with unique strings and then enumerates them.
import scipy.sparse as sp
import numpy as np
from scipy.sparse import csr_matrix
full_dict = set(train1.values.ravel().tolist() + test1.values.ravel().tolist() + train2.values.ravel().tolist() + test2.values.ravel().tolist())
print len(full_dict)
u_dict= dict()
for i, q in enumerate(full_dict):
u_dict[q] = i

shape = (len(full_dict), len(full_dict))
H = sp.lil_matrix(shape, dtype=np.int8)

def load_sparse_csr(filename):
loader = np.load(filename)
return csr_matrix((loader['data'], loader['indices'], loader['indptr']),
shape=loader['shape'])
#2) I need to speed up this part
# train_full is pandas dataframe with two columns w1 and w2 filled with strings
H = load_sparse_csr('matrix.npz')
correlation_train = []
for idx, row in train_full.iterrows():
if idx%1000 == 0: print idx
id_1 = u_dict[row['w1']]
id_2 = u_dict[row['w2']]
a_vec = H[id_1].toarray() # these vectors are of length of < 3 mil.
b_vec = H[id_2].toarray()
correlation_train.append(np.corrcoef(a_vec, b_vec)[0][1])

虽然我为如何正确地将 scipy.sparse CSR 矩阵传递给 cython 函数做出了贡献? 很久以前,我怀疑cython是否是要走的路。 特别是如果您还没有numpycython的经验。 当您将迭代计算替换为无需调用numpy或其他python代码即可转换为 C 的代码时,cython提供了最大的加速。 把pandas投入到混合中,你会有一个更大的学习曲线。

并且sparse代码的重要部分已经用cython编写了。

在不触及cython问题的情况下,我看到了几个问题。

H定义两次:

H = sp.lil_matrix(shape, dtype=np.int8)
H = load_sparse_csr('matrix.npz')

这要么是疏忽,要么是不理解Python变量是如何创建和分配的。 第二个任务取代第一个任务;因此,第一个什么都不做。 此外,第一个只是创建一个空的lil矩阵。 这样的矩阵可以迭代填充;虽然速度不快,但这是lil格式的预期用途。

第二个表达式从保存在npz文件中的数据创建新矩阵。这涉及加载的numpynpz文件以及基本的csr矩阵创建代码。 由于属性已经采用csr格式,因此无需cython触摸。

你在这里有一个迭代 - 但是在Pandas数据帧上:

for idx, row in train_full.iterrows():
id_1 = u_dict[row['w1']]
a_vec = H[id_1].toarray()

看起来您正在根据字典/数组查找选择特定的H行。 与密集矩阵索引相比,稀疏矩阵索引速度较慢。 也就是说,如果Ha = H.toarray()符合你的记忆,那么,

a_vec = Ha[id_1,:]

会快很多。

以前有人要求从稀疏矩阵中更快地选择行(或列)。 如果您可以直接处理一行的稀疏数据,我可以推荐更直接的东西。 但是你想要一个可以传递给np.corrcoef的密集数组,所以我们也必须实现toarray步骤。

如何更快地读取/遍历/切片Scipy稀疏矩阵(LIL,CSR,COO,DOK)?

最新更新