Moyen efficace de normaliser une matrice Scipy clairsemée

j'aimerais écrire une fonction qui normalise les lignes d'une grande matrice clairsemée (telle qu'elle fait la somme d'une).

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)

Cependant, cela donne l'exception suivante:

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

y a-t-il des solutions raisonnablement simples? J'ai regardé ce , mais je ne sais toujours pas comment faire la division.

21
demandé sur Community 2012-09-06 21:06:03

2 réponses

ceci a été implémenté dans scikit-learn sklearn.prétraitement.normaliser .

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

axis=1 devrait se normaliser par des lignes, axis=0 pour se normaliser par colonne. Utiliser l'argument optionnel copy=False pour modifier la matrice en place.

36
répondu Aaron McDaid 2012-09-12 22:20:02

voici ma solution.

  • transposer
  • calculer la somme de chaque col
  • format matrice diagonale B avec réciproque de la somme
  • A*B égale normalisation
  • transpose 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()
    
3
répondu sunan 2013-01-17 11:07:04