2009-04-21 5 views

Répondre

95

Il ne faut pas trop y penser. C'est finalement meilleur pour la santé mentale et la longévité de l'individu. La situation curieuse avec les types scalaires Numpy était due au fait qu'il n'y a pas de manière gracieuse et cohérente de dégrader la matrice 1x1 en types scalaires. Même si mathématiquement, ils sont la même chose, ils sont traités par un code très différent.

Si vous avez fait un peu de code scientifique, en fin de compte vous voulez que des choses comme max(a) fonctionnent sur des matrices de toutes tailles, même scalaires. Mathématiquement, c'est une chose parfaitement logique à attendre. Cependant, pour les programmeurs, cela signifie que tout ce qui présente des scalaires dans Numpy doit avoir les attributs .shape et .ndim, donc au moins les ufuncs n'ont pas besoin d'effectuer une vérification de type explicite sur son entrée pour les 21 types scalaires possibles dans Numpy. D'autre part, ils devraient également travailler avec les bibliothèques Python existantes que fait faire des vérifications de type explicites sur le type scalaire. C'est un dilemme, car un ndarray de Numpy doit changer individuellement de type quand il a été réduit à un scalaire, et il n'y a aucun moyen de savoir si cela s'est produit sans qu'il fasse des vérifications sur tous les accès. En fait, aller dans cette direction rendrait peut-être un peu ridicule de travailler avec des standards de type scalaire. La solution du développeur Numpy doit hériter à la fois des scalaires ndarray et Python pour son propre type scalaire, de sorte que tous les scalaires aient aussi .shape, .ndim, .T, etc. La matrice 1x1 sera toujours là, mais son utilisation sera découragée si vous savez que vous aurez affaire à un scalaire. Bien que cela fonctionne bien en théorie, de temps en temps, vous pouvez encore voir quelques endroits où ils ont manqué avec le rouleau de peinture, et les entrailles laids sont exposés aux yeux de tous:

>>> from numpy import * 
>>> a = array(1) 
>>> b = int_(1) 
>>> a.ndim 
0 
>>> b.ndim 
0 
>>> a[...] 
array(1) 
>>> a[()] 
1 
>>> b[...] 
array(1) 
>>> b[()] 
1 

Il n'y a vraiment aucune raison pour a[...] et a[()] devrait retourner des choses différentes, mais ça le fait. Il y a des propositions en place pour changer cela, mais on dirait qu'ils ont oublié de finir le travail pour les tableaux 1x1.

Un problème potentiellement plus grand, et peut-être non résoluble, est le fait que les scalaires Numpy sont immuables. Par conséquent, "pulvériser" un scalaire dans un ndarray, mathématiquement l'opération adjointe de réduire un tableau en un scalaire, est un PITA à implémenter. Vous ne pouvez pas développer réellement un scalaire Numpy, il ne peut pas, par définition, être jeté dans un ndarray, même si newaxis fonctionne mystérieusement sur elle:

>>> b[0,1,2,3] = 1 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'numpy.int32' object does not support item assignment 
>>> b[newaxis] 
array([1]) 

Matlab, de plus en plus la taille d'un scalaire est un tout à fait acceptable et écervelé opération. Dans Numpy vous devez coller a = array(a) discordant partout où vous pensez vous auriez la possibilité de commencer avec un scalaire et finir avec un tableau.Je comprends pourquoi Numpy doit être aussi sympa avec Python, mais cela ne change rien au fait que beaucoup de nouveaux switchers sont profondément confus à ce sujet. Certains ont le souvenir explicite de lutter contre ce comportement et finalement de persévérer, tandis que d'autres qui sont trop loin sont généralement laissés avec une profonde cicatrice mentale informe qui hante souvent leurs rêves les plus innocents. C'est une situation laide pour tous.

+21

+1 pour l'introduction philosophique :-) –

+3

Avez-vous pensé à une carrière d'écriture? – KobeJohn

+4

Beaucoup de ceci semble être la façon matlab de regarder les choses-_ "Vous ne pouvez pas réellement développer un scalaire Numpy" _ - ni de développer un np.array. Être explicite sur les tailles rend le comportement accidentel de O (N^2) plus difficile. _ "il ne peut pas être jeté par définition dans un ndarray" _ - c'est ce que fait np.asarray (scalar) '. _ "la matrice 1x1 ..." _ - penser que les choses sont intrinsèquement 2D, ou en tant que matrices, n'est pas utile ici – Eric

4

Vous devez créer le tableau scalaire un peu différemment:

>>> x = numpy.float64(1.111) 
>>> x 
1.111 
>>> numpy.isscalar(x) 
True 
>>> numpy.ndim(x) 
0 

Il ressemble scalars in numpy peut être un peu différent de ce que concept de vous peut être utilisé à partir d'un point de vue purement mathématique. Je suppose que vous pensez en termes de matrices scalaires?

Questions connexes