如何加快计算速度?

时间:2017-02-09 15:06:44

标签: python numpy scipy sparse-matrix

我需要计算100万* 100万次计算来填充稀疏矩阵。但是当我使用循环逐行填充矩阵时,我发现只需要6分钟就能完成100 * 100的计算。所以任务将无法解决。有哪些方法可以加快这个过程?

import numpy as np
from scipy.sparse import lil_matrix
import pandas as pd  
tp = pd.read_csv('F:\\SogouDownload\\train.csv', iterator=True, chunksize=1000)  
data = pd.concat(tp, ignore_index=True) 
matrix=lil_matrix((1862220,1862220))
for i in range(1,1862220):
    for j in range(1,1862220):
        matrix[i-1,j-1]=np.sum(data[data['source_node']==i].destination_node.isin(data[data['source_node']==j].destination_node))

2 个答案:

答案 0 :(得分:0)

虽然不是构建稀疏矩阵的最快方法,但这也不是非常慢,至少不是lil分配步骤:

In [204]: N=100
In [205]: M=sparse.lil_matrix((N,N))
In [206]: for i in range(N):
     ...:     for j in range(N):
     ...:         M[i,j]=(i==j)
In [207]: M
Out[207]: 
<100x100 sparse matrix of type '<class 'numpy.float64'>'
    with 100 stored elements in LInked List format>

它只将非零值保存到M。我几乎没有看到循环中的延迟。

所以我的猜测是大部分时间花在panadas索引表达式上:

np.sum(data[data['source_node']==i].destination_node.isin(data[data['source_node']==j].destination_node))

将数据(通常是文本的)转换为协同计数稀疏矩阵经常出现。它们用于学习代码,模式搜索等。scikit-learn经常被使用。还tensorflow

对于N = 1000

In [212]: %%timeit
     ...: M=sparse.lil_matrix((N,N))
     ...: for i in range(N):
     ...:       for j in range(N):
     ...:           M[i,j]=(i==j)
     ...: 
1 loop, best of 3: 7.31 s per loop

迭代地将这些值分配给密集数组会更快,即使我们在最后包含转换为稀疏。

In [213]: %%timeit
     ...: M=np.zeros((N,N))
     ...: for i in range(N):
     ...:       for j in range(N):
     ...:           M[i,j]=(i==j)
     ...: 
1 loop, best of 3: 353 ms per loop

In [214]: %%timeit
     ...: M=np.zeros((N,N))
     ...: for i in range(N):
     ...:       for j in range(N):
     ...:           M[i,j]=(i==j)
     ...: M = sparse.lil_matrix(M)
     ...: 
1 loop, best of 3: 353 ms per loop

但是对于非常大的情况,创建中间密集阵列可能会遇到内存问题。

答案 1 :(得分:0)

这里使用的技术是稀疏矩阵乘法。但对于该技术,您首先需要将源节点映射到目标节点的二进制矩阵(节点标签将是非零条目的索引)。

from scipy.sparse import csr_matrix

I = data['source_node'] - 1
J = data['destination_node'] - 1
values = np.ones(len(data), int)
shape = (np.max(I) + 1, np.max(J) + 1)
mapping = csr_matrix((values, (I, J)), shape)

该技术本身只是该矩阵与其转置的矩阵乘法(另见this question)。

cooccurrence = mapping.dot(mapping.T)

唯一可能的问题是生成的矩阵可能不稀疏并消耗所有RAM。