2012-09-06 7 views
18

Büyük bir seyrek matrisin satırlarını normalleştiren bir işlev yazmak istiyorum (birebir olduğu gibi). Bir Scipy Sparse Matrix'i normalize etmenin etkili yolu

File "/usr/lib/python2.6/dist-packages/scipy/sparse/base.py", line 325, in __div__ 
    return self.__truediv__(other) 
File "/usr/lib/python2.6/dist-packages/scipy/sparse/compressed.py", line 230, in __truediv__ 
    raise NotImplementedError 

herhangi makul basit çözümler var mıdır:

from pylab import * 
import scipy.sparse as sp 

def normalize(W): 
    z = W.sum(0) 
    z[z < 1e-6] = 1e-6 
    return W/z[None,:] 

w = (rand(10,10)<0.1)*rand(10,10) 
w = sp.csr_matrix(w) 
w = normalize(w) 

Ancak bu şu istisna verir? this numaralı telefonu inceledim, ancak bölümün nasıl yapıldığını hala belirsiz hâle getiriyorum.

+3

eşittir Bu temelde bir kopyasıdır: http: //stackoverflow.c om/questions/12237954/çarpma-elemanları-in-a-seyrek-dizi-satır-in-matris ile satır sıralı çarpma veya bölme bir satır olup olmadığı önemli değildir. Tabii ki birisi daha iyi bir cevabı varsa, harika :) – seberg

+0

Harika - teşekkürler! – sterne

+0

Katılmıyorum, bu farklı bir sorundur. İşaret ettiğin yineleme, eleman-bilge çoğaltır, oysa bu soru, her sırayı farklı bir değere bölmek ister (aynı değerde sıfır olmayan elemanlar yerine). Aaron McDaid'in aşağıdaki çözümü verimli bir şekilde çalışmalı (ve herhangi bir verinin kopyalanmasını gerektirmez). – conradlee

cevap

29

Bu, scikit-learn sklearn.preprocessing.normalize adresinde uygulanmıştır.

from sklearn.preprocessing import normalize 
w_normalized = normalize(w, norm='l1', axis=1) 

axis=1

kolonu ile normalize etmek için, satır ile axis=0 normale gerekir. Matrisi yerinde değiştirmek için isteğe bağlı argümanını copy=False kullanın.

+2

Özelliklere göre normalleştiriyorsanız (axis = 0), döndürülmüş matrisin "csc" türünde olduğunu unutmayın. w bir 'csr' olsaydı bile. Bir 'csr' olmanın üzerine saydıysanız bu hoş olmayabilir – Leo

3

İşte benim çözümüm.

  • devrik her col toplamının ile karşılıklı
  • biçimi köşegen matris B bir
  • hesaplamak toplam
  • A * B Normalleştirme
  • devrik Cı

    import scipy.sparse as sp 
    import numpy as np 
    import math 
    
    minf = 0.0001 
    
    A = sp.lil_matrix((5,5)) 
    b = np.arange(0,5) 
    A.setdiag(b[:-1], k=1) 
    A.setdiag(b) 
    print A.todense() 
    A = A.T 
    print A.todense() 
    
    sum_of_col = A.sum(0).tolist() 
    print sum_of_col 
    c = [] 
    for i in sum_of_col: 
        for j in i: 
         if math.fabs(j)<minf: 
          c.append(0) 
         else: 
          c.append(1/j) 
    
    print c 
    
    B = sp.lil_matrix((5,5)) 
    B.setdiag(c) 
    print B.todense() 
    
    C = A*B 
    print C.todense() 
    C = C.T 
    print C.todense()