我需要计算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))
答案 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。