2017-02-09 132 views
-1

我需要計算一個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)) 
+5

向我們展示您的代碼將是一個好的開始。並且10^12的計算是過高的。 –

+0

你的矩陣多麼稀疏?通常情況下,一個使用字典的方法至關重要的是矩陣座標工作。 – jsbueno

+0

這是Python 2還是3?如果是2,則應該使用'xrange'而不是'range'。 –

回答

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)) 

轉換數據,經常是文本,進入coocurance數稀疏矩陣經常出現。它們用於學習代碼,模式搜索等。經常使用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 

但是對於非常大的情況,創建中間密集數組可能會遇到內存問題。

+0

感謝您的幫助。事實上,我無法創建如此大的密集數組。實際的方式似乎減少了維度。而且我同意這是指數表達式減緩了這個過程。 – martin

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。