64 votes

Pourquoi les tableaux 0d dans Numpy ne sont-ils pas considérés comme scalaires?

Certes, un tableau 0d est scalaire, mais Numpy ne semble pas le penser ... est-ce que je manque quelque chose ou est-ce que je ne comprends tout simplement pas le concept?

 >>> foo = numpy.array(1.11111111111, numpy.float64)
>>> numpy.ndim(foo)
0
>>> numpy.isscalar(foo)
False
>>> foo.item()
1.11111111111
 

131voto

Tim Lin Points 681

Il ne faut pas trop réfléchir à ce sujet. C'est enfin le meilleur pour la santé mentale et la longévité de l'individu.

La situation curieuse avec Numpy scalaire-types a été alésage du fait qu'il n'y a pas de gracieux et de manière cohérente à dégrader la matrice 1x1 à des types scalaires. Même si mathématiquement c'est la même chose, ils sont gérés par code très différent.

Si vous avez été faire tout montant de scientifiques de code, en fin de compte, vous voulez des choses comme max(a) de travailler sur des matrices de toutes les tailles, même les scalaires. Mathématiquement, c'est parfaitement sensé attendre. Toutefois, pour les programmeurs, cela signifie que, quelle que soit présente scalaires dans Numpy devraient avoir le .la forme et .ndim attirbute, au moins la ufuncs n'avez pas à faire de type explicite de vérifier sur son entrée pour le 21 possible des types scalaires dans Numpy.

D'autre part, ils doivent aussi travailler avec les bibliothèques Python qui ne ne de type explicite-vérifications de type scalaire. C'est un dilemme, car un Numpy ndarray ont, individuellement, d'en modifier le type quand il a été réduit à un scalaire, et il n'y a aucun moyen de savoir si cela a eu lieu sans devoir procéder à des vérifications sur tous les accès. Va effectivement que la route serait probablement peu ridiculement lent de travailler avec un type scalaire normes.

Le Numpy du développeur de la solution est d'hériter de deux ndarray et Python scalaires pour son propre scalary type, de sorte que tous les scalaires ont également .la forme, la .ndim, .T, etc etc. La matrice 1x1 sera toujours là, mais son utilisation est déconseillée si vous savez que vous allez avoir affaire à un scalaire. Alors que cela devrait bien fonctionner, en théorie, de temps en temps on pouvait encore voir certains des endroits où ils ont raté avec le rouleau à peinture, et le truand les entrailles exposée 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[()]
array(1)

Il n'y a vraiment aucune raison pourquoi a[...] et a[()] devraient retour des choses différentes, mais il n'. Il y a des propositions en place pour changer cela, mais on dirait qu'ils ont oublié de terminer le travail pour 1x1 tableaux.

Un potentiellement plus grande, et peut-être non-résolu problème, c'est le fait que Numpy scalaires sont immuables. Par conséquent, "pulvérisation" un scalaire dans un ndarray, mathématiquement, l'adjoint fonctionnement de l'effondrement d'un tableau en un scalaire, est un pain PITA à mettre en œuvre. Vous ne pouvez pas faire pousser un Numpy scalaire, il ne peut pas, par définition, être jeté dans un ndarray, même si newaxis mystérieusement fonctionne 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])

Dans Matlab, la croissance de la taille d'un scalaire est parfaitement acceptable et sans cervelle opération. Dans Numpy vous avez à coller à des secousses a = array(a) partout où vous pensez que vous auriez la possibilité de commencer par un scalaire et de se retrouver avec un tableau. Je comprends pourquoi Numpy a à être de cette façon de jouer gentil avec Python, mais cela ne change pas le fait que beaucoup de nouveaux commutateurs sont profondément confus au sujet de ce. Certains ont la mémoire explicite de la difficulté avec ce type de comportement et finalement, persévérante, alors que d'autres qui sont allés trop loin sont généralement de gauche avec une certaine profondeur informes mentale cicatrice qui souvent hante leurs rêves innocents. C'est une horrible situation pour tous.

6voto

Jason Baker Points 56682

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 semble que les scalaires dans numpy soient un concept un peu différent de ce à quoi vous êtes habitué d'un point de vue purement mathématique. Je suppose que vous pensez en termes de matrices scalaires?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X