web-dev-qa-db-fra.com

scipy csr_matrix: comprendre indptr

De temps en temps, je peux manipuler un csr_matrix Mais j'oublie toujours comment les paramètres indices et indptr fonctionnent ensemble pour construire une matrice clairsemée.

Je cherche une explication claire et intuitive sur la façon dont le indptr interagit avec les paramètres data et indices lors de la définition d'une matrice clairsemée à l'aide de la notation csr_matrix((data, indices, indptr), [shape=(M, N)]).

Je peux voir dans la documentation scipy que le paramètre data contient toutes les données non nulles, et le paramètre indices contient les colonnes associées à ces données (en tant que telles , indices est égal à col dans l'exemple donné dans la documentation). Mais comment expliquer clairement le paramètre indptr?

14
Tanguy

Peut-être que cette explication peut aider à comprendre le concept:

  • data est un tableau contenant tous les éléments non nuls de la matrice clairsemée.
  • indices est un tableau mappant chaque élément de data à sa colonne dans la matrice clairsemée.
  • indptr mappe ensuite les éléments de data et indices aux lignes de la matrice clairsemée. Cela se fait avec le raisonnement suivant:

    1. Si la matrice clairsemée a [~ # ~] m [~ # ~] lignes, indptr est un tableau contenant M + 1 éléments
    2. pour la ligne i , [indptr[i]:indptr[i+1]] renvoie les indices des éléments à prendre parmi data et indices correspondant à la ligne i . Supposons donc indptr[i]=k et indptr[i+1]=l, les données correspondant à la ligne i seraient data[k:l] aux colonnes indices[k:l]. C'est la partie délicate, et j'espère que l'exemple suivant aide à le comprendre.

[~ # ~] modifier [~ # ~] : j'ai remplacé les chiffres dans data par des lettres pour éviter toute confusion dans l'exemple suivant .

enter image description here

Remarque: les valeurs dans indptr augmentent nécessairement, car la cellule suivante dans indptr (la ligne suivante) fait référence aux valeurs suivantes dans data et indices correspondant à cette ligne.

20
Tanguy

Bien sûr, les éléments à l'intérieur d'indptr sont en ordre croissant. Mais comment expliquer le comportement indptr? En bref, jusqu'à ce que l'élément dans indptr soit identique ou n'augmente pas, vous pouvez ignorer l'index de ligne de la matrice clairsemée.

L'exemple suivant illustre l'interprétation ci-dessus des éléments indptr:

Exemple 1) imaginez cette matrice:

array([[0, 1, 0],
       [8, 0, 0],
       [0, 0, 0],
       [0, 0, 0],
       [0, 0, 7]])


mat1 = csr_matrix(([1,8,7], [1,0,2], [0,1,2,2,2,3]), shape=(5,3))
mat1.indptr
# array([0, 1, 2, 2, 2, 3], dtype=int32)
mat1.todense()  # to get the corresponding sparse matrix

Exemple 2) Tableau vers CSR_matrix (le cas où la matrice clairsemée existe déjà):

arr = np.array([[0, 0, 0],
                [8, 0, 0],
                [0, 5, 4],
                [0, 0, 0],
                [0, 0, 7]])


mat2 = csr_matrix(arr))
mat2.indptr
# array([0, 0, 1, 3, 3, 4], dtype=int32)
mat2.indices
# array([0, 1, 2, 2], dtype=int32)
mat.data
# array([8, 5, 4, 7], dtype=int32)
1
A. Nadjar