web-dev-qa-db-fra.com

Comment accéder aux éléments matriciels clairsemés?

type(A)
<class 'scipy.sparse.csc.csc_matrix'>
A.shape
(8529, 60877)
print A[0,:]
  (0, 25)   1.0
  (0, 7422) 1.0
  (0, 26062)    1.0
  (0, 31804)    1.0
  (0, 41602)    1.0
  (0, 43791)    1.0
print A[1,:]
  (0, 7044) 1.0
  (0, 31418)    1.0
  (0, 42341)    1.0
  (0, 47125)    1.0
  (0, 54376)    1.0
print A[:,0]
  #nothing returned

Maintenant, ce que je ne comprends pas, c'est quand je tape A [1 ,:] qui devrait sélectionner les éléments de la 2ème ligne, mais j'obtiens des éléments de la 1ère ligne dans l'impression. Lorsque je tape A [:, 0], cela devrait renvoyer la première colonne mais je ne reçois rien d'imprimé. Pourquoi?

36
siamii

A[1,:] est lui-même une matrice clairsemée de forme (1, 60877). This est ce que vous imprimez, et il n'a qu'une seule ligne, donc toutes les coordonnées de ligne sont 0.

Par exemple:

In [41]: a = csc_matrix([[1, 0, 0, 0], [0, 0, 10, 11], [0, 0, 0, 99]])

In [42]: a.todense()
Out[42]: 
matrix([[ 1,  0,  0,  0],
        [ 0,  0, 10, 11],
        [ 0,  0,  0, 99]], dtype=int64)

In [43]: print(a[1, :])
  (0, 2)    10
  (0, 3)    11

In [44]: print(a)
  (0, 0)    1
  (1, 2)    10
  (1, 3)    11
  (2, 3)    99

In [45]: print(a[1, :].toarray())
[[ 0  0 10 11]]

Vous pouvez sélectionner des colonnes, mais s'il n'y a aucun élément différent de zéro dans la colonne, rien ne s'affiche lors de sa sortie avec print:

In [46]: a[:, 3].toarray()
Out[46]: 
array([[ 0],
       [11],
       [99]])

In [47]: print(a[:,3])
  (1, 0)    11
  (2, 0)    99

In [48]: a[:, 1].toarray()
Out[48]: 
array([[0],
       [0],
       [0]])

In [49]: print(a[:, 1])


In [50]:

Le dernier appel print n'affiche aucune sortie car la colonne a[:, 1] n'a aucun élément différent de zéro.

36
Warren Weckesser

Pour répondre à la question de votre titre en utilisant une technique différente de celle de votre question:

csc_matrix Vous donne la méthode .nonzero().

Donné:

>>> import numpy as np
>>> from scipy.sparse.csc import csc_matrix
>>> 
>>> row = np.array( [0, 1, 3])
>>> col = np.array( [0, 2, 3])
>>> data = np.array([1, 4, 16])
>>> A = csc_matrix((data, (row, col)), shape=(4, 4))

Vous pouvez accéder aux index ponitant aux données non nulles en:

>>> rows, cols = A.nonzero()
>>> rows
array([0, 1, 3], dtype=int32)
>>> cols
array([0, 2, 3], dtype=int32)

Que vous pouvez ensuite utiliser pour accéder à vos données, sans jamais avoir besoin de faire une version dense de votre matrice clairsemée:

>>> [((i, j), A[i,j]) for i, j in Zip(*A.nonzero())]
[((0, 0), 1), ((1, 2), 4), ((3, 3), 16)]
15
TheGrimmScientist

Si c'est pour calculer le score TFIDF en utilisant TfidfTransformer, vous pouvez obtenir l'IDF par tfidf.idf_. Ensuite, le nom du tableau clairsemé, dites 'a', a.toarray().

toarray renvoie un ndarray; todense renvoie une matrice. Si vous voulez une matrice, utilisez todense; sinon, utilisez toarray.

1
Satyam

Je reconnais pleinement toutes les autres réponses données. Il s'agit simplement d'une approche différente.

Pour illustrer cet exemple, je crée une nouvelle matrice clairsemée:

from scipy.sparse.csc import csc_matrix
a = csc_matrix([[1, 0, 0, 0], [0, 0, 10, 11], [0, 0, 0, 99]])
print(a)

Sortie:

(0, 0)  1
(1, 2)  10
(1, 3)  11
(2, 3)  99

Pour y accéder facilement, comme la façon dont nous accédons à une liste, je l'ai convertie en liste.

temp_list = []
for i in a:
    temp_list.append(list(i.A[0]))

print(temp_list)

Sortie:

[[1, 0, 0, 0], [0, 0, 10, 11], [0, 0, 0, 99]]

Cela peut sembler stupide, car je crée une matrice clairsemée et la reconvertis, mais il existe certaines fonctions comme TfidfVectorizer et d'autres qui retournent une matrice clairsemée en sortie et les manipulant peuvent être difficiles. C'est une façon d'extraire des données d'une matrice clairsemée.

1
Rohan Pillai