2012-09-06 75 views
18

我想寫一個函數來標準化大型稀疏矩陣的行(使它們總和爲1)。標準化Scipy稀疏矩陣的有效方法

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) 

然而,這給出了以下異常:

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 

是否有任何合理的簡單的解決方案?我曾看過this,但我怎麼實際做這個部門還不清楚。

+3

這基本上是一個重複的:http://stackoverflow.c om/questions/12237954/multiplying-elements-in-a-sparse-array-with-rows-in-matrix,因爲不管它是逐行逐行乘法還是除法都不重要。當然,如果有人有更好的答案,很好:) – seberg

+0

偉大 - 謝謝! – sterne

+0

我不同意,這是一個不同的問題。您指出的重複做了元素方式的乘法運算,而這個問題似乎想要將每一行除以不同的值(而不是所有非零元素的值相同)。以下Aaron McDaid的解決方案應該有效地工作(並且不需要任何數據的複製)。 – conradlee

回答

29

這已在scikit-learn sklearn.preprocessing.normalize中實施。

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

axis=1應行正常化,axis=0柱正常化。使用可選參數copy=False修改矩陣。

+2

請注意,如果你規範化的功能(axis = 0),那麼返回的矩陣類型'csc'即使w是'csr'。如果你認爲這是一個'csr',這可能會令人不愉快, – Leo

3

這是我的解決方案。

  • 轉置各欄與總和的倒數
  • 格式對角矩陣B的
  • 計算總和
  • A * B等於正常化
  • 轉置Ç

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