2016-04-12 15 views
0

Şu anda her satırın üzerinde numaralandırdığım ve her satırdaki bilgilere göre bazı hesaplamalar yaptığım seyrek bir matrisim var. Her sıra diğerlerinden tamamen bağımsızdır. Ancak, büyük matrisler için, bu kod çok yavaştır (yaklaşık 2 saat sürer) ve matrisi yoğun olana dönüştüremiyorum (8GB RAM ile sınırlı).Scipy Sparse Matrix'i Optimize Edin

import scipy.sparse 
import numpy as np 

def process_row(a, b): 
    """ 
    a - contains the row indices for a sparse matrix 
    b - contains the column indices for a sparse matrix 

    Returns a new vector of length(a) 
    """ 

    return 

def assess(mat): 
    """ 
    """ 
    mat_csr = mat.tocsr() 
    nrows, ncols = mat_csr.shape 
    a = np.arange(ncols, dtype=np.int32) 
    b = np.empty(ncols, dtype=np.int32) 
    result = [] 

    for i, row in enumerate(mat_csr): 
     # Process one row at a time 
     b.fill(i) 
     result.append(process_row(b, a)) 

    return result 

if __name__ == '__main__': 
    row = np.array([8,2,7,4]) 
    col = np.array([1,3,2,1]) 
    data = np.array([1,1,1,1]) 

    mat = scipy.sparse.coo_matrix((data, (row, col))) 
    print assess(mat) 

ben çok daha hızlı gerçekleştirir, böylece daha iyi bu tasarlamak için herhangi bir yolu var olup olmadığını görmek için arıyorum. Temel olarak, process_row işlevi (satır, col) dizin çiftlerini alır (a, b) ve başka bir seyrek matris kullanarak bazı matematik yapar ve bir sonuç döndürür. Bu işlevi değiştirme seçeneğim yok, ancak aslında farklı satır/sütun çiftlerini işleyebilir ve aynı satırdaki herşeyi işlemekle sınırlı değil.

cevap

0

Senin sorunun bu diğer yeni SO soruya benzer:

Calculate the euclidean distance in scipy csr matrix

Cevabıma ben seyrek matris satır yinelemek için bir yol çizdi. Diziyi lil'a dönüştürmenin daha hızlı olduğunu ve yoğun satırları doğrudan alt listelerinden oluşturduğunu düşünüyorum. Bu, her satır için yeni bir seyrek matris oluşturmanın ek yükünü ortadan kaldırır. Ama ben zaman testleri yapmadım.

https://stackoverflow.com/a/36559702/901925

Belki bu durumda da geçerlidir.