2010-04-20 17 views
4

J'ai un scipy.sparse.dok_matrix (dimensions mx n), voulant ajouter un tableau entier avec une longueur m.Ajout d'un tableau numpy à un scipy.sparse.dok_matrix

for col in xrange(n): 
    dense_array = ... 
    dok_matrix[:,col] = dense_array 

Cependant, ce code soulève une exception dans dok_matrix.__setitem__ quand il tente de supprimer une clé non existante (del self[(i,j)]).

Donc, pour l'instant je fais cela la façon unelegant:

for col in xrange(n): 
    dense_array = ... 
    for row in dense_array.nonzero(): 
     dok_matrix[row, col] = dense_array[row] 

Ce sent très ineffecient. Alors, quel est le moyen le plus efficace de le faire?

Merci!

Répondre

2

Je suis surpris que votre manière unelegant n'a pas les mêmes problèmes que la manière de la tranche. Cela ressemble à un bug sur moi en regardant le code Scipy. Lorsque vous essayez de définir une certaine ligne et une colonne dans un dok_matrix à zéro quand il est déjà zéro, il y a une erreur car il essaie de supprimer la valeur de cette ligne et colonne sans vérifier si elle existe.

En réponse à votre question, ce que vous faites de façon inélégante est exactement ce que la méthode __setitem__ fait actuellement avec votre méthode élégante (après quelques vérifications isinstance et autres). Si vous voulez utiliser la manière élégante, vous pouvez corriger le bug je l'ai mentionné dans votre paquet Scipy en ouvrant dok.py en Lib/site-packages/scipy/sparse/ et en changeant la ligne 222 de

if value==0: 

à

if value==0 and self.has_key((i,j)): 

Ensuite, vous pouvez utiliser la manière élégante et cela devrait fonctionner très bien. Je suis allé soumettre un correctif, mais celui-ci est déjà corrigé pour la prochaine version et c'est ainsi que cela a été corrigé.

+0

La façon « unelegant » filtre les zéros avec 'dense_array.nonzeros()' avant d'insérer des valeurs dans dok_matrix, c'est pourquoi il ne tombe pas en panne. Merci beaucoup! – PhilS

+0

Doh, raté ça, mais content de pouvoir aider. –

+0

side-note: Je pense que le code indiqué ci-dessus dans 'dok.py' est bogué, car les valeurs zéro sont définies dans' dok_matrix' si la clé (i, j) n'existe pas encore. J'ai ouvert un ticket (http://projects.scipy.org/scipy/ticket/1160). De plus, mon comportement "unelegant" fonctionne beaucoup mieux si 'dense_array' est clairsemé, car seules les valeurs non nulles doivent être vérifiées et insérées (' __setitem__' ne leur est demandé). Donc, je m'en tiens à mon ancienne version, bien que celle que vous avez mentionnée soit plus belle ... – PhilS

1

Je pense que ce bug a été corrigé dans Scipy 0.8.0

+0

Oui, c'est vrai. – PhilS