2013-01-18 5 views
8

lecteur longue durée, premier éditeur.type (s) d'opérande non pris en charge pour *: 'numpy.ndarray' et 'numpy.float64'

J'ai cherché autour de google et empiler le débordement, mais n'a pas vraiment été capable de trouver une réponse générale à cette question. Je reçois un "type d'opérande non supporté pour *: 'numpy.ndarray' et 'numpy.float64'" dans python 2.7.3 en utilisant numpy 1.6.2. L'erreur provient de la multiplication d'un tableau numpy et d'un float numpy, mais cela n'arrive pas à chaque fois.

Par exemple:

x = np.tan(1) # numpy.float64 
y = np.array([0,1,2,3]) # numpy.ndarray 
np.multiply(x,y) # works no problem 

Ou

x = np.tan(np.abs(np.multiply(-31,41))) # numpy.float64 
y = np.square(np.add(np.divide(np.zeros(100),42),(-27)**40)) # numpy.ndarray 
np.multiply(x,y) # works no problem 

deux travaillent

Maintenant, pour les enfants de problème:

np.multiply(np.square(np.add(np.divide(np.zeros(100),42),-27)**40)), 
np.tan(np.abs(np.multiply(-31,41)))) 

ou, avec x définis comme ci-dessus:

np.multiply(np.square(np.add(np.divide(np.zeros(100),42),(-27)**40)),x) 

les deux produisent l'erreur: NotImplemented

Je connais les fonctions et de nombres aléatoires sembler étrange, mais sur le plan conceptuel cela devrait fonctionner, comme cela a fonctionné lorsque les deux ont été mis à des variables individuellement.

Pourquoi cela se produit-il? Comment puis-je le réparer dans un sens général?

Merci beaucoup! Jason

+0

Je pense que vous avez attrapé un bug dans le code, vous pouvez le signaler à la personnes numpy. Pour l'enregistrement, si 'a' est' np.ndarray' et 'x' est' np.float64', alors à la fois 'x * a' et' a * x [...] 'fonctionnent, mais aucun de' a * x', 'a + x',' a/x' ou 'a - x' font. Il est difficile de comprendre pourquoi, si la méthode '__mul__' de' a' ne peut pas le gérer, '__rmul__' de 'x' n'est pas appelé, car il semble savoir comment gérer le cas ... – Jaime

+0

Merci beaucoup pour vérifier cela pour moi. Je vais essayer de le signaler comme un problème en numpy. Pensez-vous qu'il existe peut-être un moyen de contourner ce problème? – Jason

+0

Si vous remplacez 'x' par' x [...] 'cela fonctionne, mais c'est un hack méchant ... – Jaime

Répondre

7

Je suppose que le problème ici est que NumPy ne peut pas stocker les valeurs Python long dans ses tableaux. Dès que vous essayez de le faire, il passe le type de données du tableau à object. Les opérations arithmétiques sur le tableau deviennent alors plus compliquées car NumPy ne peut plus faire l'arithmétique elle-même.

>>> np.array(27**40) 
array(1797010299914431210413179829509605039731475627537851106401L, dtype=object) 
>>> np.array(27**40) * np.tan(1) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unsupported operand type(s) for *: 'numpy.ndarray' and 'numpy.float64' 

Étrangement, la permutation de l'ordre des arguments peuvent parfois travailler:

>>> np.tan(1) * np.array(27**40) 
2.7986777223711575e+57 

Dans ce second cas, le type du résultat est un Python float, pas un tableau numpy.

La solution est d'éviter de créer des long valeurs dans les tableaux numpy et utiliser float s au lieu:

>>> np.array(27.0**40) 
array(1.797010299914431e+57) 
>>> np.array(27.0**40) * np.tan(1) 
2.7986777223711575e+57 
>>> np.multiply(np.square(np.add(np.divide(np.zeros(10),42),(-27.0)**40)),np.tan(1)) 
array([ 5.02925269e+114, 5.02925269e+114, 5.02925269e+114, 
     5.02925269e+114, 5.02925269e+114, 5.02925269e+114, 
     5.02925269e+114, 5.02925269e+114, 5.02925269e+114, 
     5.02925269e+114]) 

Si vous obtenez une erreur comme celui-ci est l'avenir, la première chose à faire est de vérifier la dtype du tableau en cours de multiplication. Contient-il des valeurs NumPy ou des objets Python?

+0

Bon appel! Ma variable tableau (y = np.square (np.add (np.divide (np.zeros (100), 42), (- 27) ** 40)) comme défini ci-dessus dans ma question) a un type 'objet' (Malheureusement, je ne suis pas sûr de pouvoir le forcer à être un flotteur, vu qu'il commence comme un flotteur, et quelque part le long du chemin se jette à une longue. – Jason

+0

C'est l'opération avec '(-27) ** 40' qui pose problème. NumPy ne peut pas gérer directement 'long's Python. Cependant, vous pouvez utiliser 'np.array' pour convertir un tableau NumPy en un autre tableau d'un type différent. Par exemple, 'np.array (np.array (27 ** 40), dtype = np.float64)' retournera un tableau de type 'float64'. –

+0

Oui, j'ai pu trouver où les ints 27 et 40 étaient générés dans mon code, et les lancer comme des flotteurs. Pour l'enregistrement, np.arange génère int32. La plupart des fonctions numpy fonctionnent dans les flottants, y compris np.ones et np.zeros – Jason

-1

Est-ce un quiz? Je ne comprends pas pourquoi la question est si obfusquée ... Tout se résume à ce simple fait.

Compte tenu

>>> x = 10**100 
>>> type(x) 
<type 'long'> 
>>> y = np.float64(1) 

nous avons

>>> y.__mul__(x) 
1e+100 
>>> y.__rmul__(x) 
NotImplemented 

Ceci est le bug (ou fonctionnalité, je ne sais pas) car il devrait être y.__mul__(x) == y.__rmul__(x) (au moins pour ces valeurs particulières de x et y).

Python long ne sait pas comment gérer la multiplication avec numpy.float64 (mais cela est correct.)

>>> x.__mul__(y) 
NotImplemented 
>>> x.__rmul__(y) 
NotImplemented 

Alors y*x est évaluée à y.__mul__(x) et donne le résultat attendu. Au contraire x*y est d'abord essayé comme x.__mul__(y) (non implémenté, OK) que comme y.__rmul__(x) (pas implémenté mais un bug.).

Comme déjà souligné, nous pouvons avoir nd.arrays d'objets arbitraires, et tout devient clair.

Modifier

Ce bogue a été corrigé (probablement numpy ver 1.7.):

>>> np.version.version 
'1.13.1' 
>>> x = 10**100 
>>> y = np.float64(1) 
>>> x.__mul__(y) 
NotImplemented 
>>> x.__rmul__(y) 
NotImplemented 
>>> y.__mul__(x) 
1e+100 
>>> y.__rmul__(x) 
1e+100 
>>> x*y 
1e+100 
>>> y*x 
1e+100 
+0

Pourquoi est-ce downvoted? – Worthy7

+0

@ Worthy7 Aucune idée de pourquoi ma réponse a été downvoted: À mon humble avis, il met en évidence le bug numpy responsable du comportement inattendu, tel que confirmé par https://github.com/numpy/numpy/issues/2930#issuecomment-12445232 (et non, je n'a pas écrit ma réponse après avoir lu cette question numpy.) –

Questions connexes