2013-01-18 10 views
8

Langzeitleser, Erstverfasser.nicht unterstützte Operandentyp (en) für *: 'numpy.darray' und 'numpy.float64'

Ich suchte auf Google und Stack-Überlauf, aber war nicht wirklich in der Lage, eine allgemeine Antwort auf diese Frage zu finden.

Ich bekomme einen "nicht unterstützten Operandentyp (en) für *: 'numpy.darray' und 'numpy.float64'" Fehler in Python 2.7.3 mit numpy 1.6.2.

Der Fehler kommt von der Multiplikation eines numpy-Arrays und eines numpy float, aber es passiert nicht jedes Mal.

Zum Beispiel:

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

Oder

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 

Beide arbeiten

Jetzt für die Problemkinder:

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

oder mit x wie oben definiert:

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

produzieren sowohl den Fehler: NotImplemented

Ich weiß, dass die Zufallsfunktionen und Zahlen seltsam erscheinen, aber vom Konzept her sollte dies immer noch funktionieren, da sie beide arbeiteten, wenn sie einzeln auf Variablen gesetzt wurden.

Warum passiert das? Wie kann ich es in einem allgemeinen Sinn beheben?

Vielen Dank! Jason

+0

Ich glaube, Sie einen Fehler im Code gefangen haben, möchten Sie vielleicht es die berichten numpige Leute. Wenn 'a'' np.darray' ist und 'x'' np.float64' ist, dann funktionieren sowohl 'x * a' als auch' a * x [...], aber keiner von 'a * x', 'a + x',' a/x' oder 'a-x' machen. Es ist schwer zu verstehen, warum, wenn die '__mul__' Methode von' a' nicht damit umgehen kann, '__rulul__' von' x' nicht aufgerufen wird, da es den Fall zu verstehen scheint ... – Jaime

+0

Vielen Dank das für mich überprüfen. Ich werde versuchen, es als ein Problem in numpy zu melden. Denkst du, dass es einen Weg gibt, um dies zu umgehen? – Jason

+0

Wenn Sie 'x' durch' x [...] 'ersetzen, funktioniert es, aber es ist ein hässlicher Hack ... – Jaime

Antwort

7

Ich vermute, dass das Problem hier ist, dass NumPy Python long Werte in seinen Arrays nicht speichern kann. Sobald Sie dies versuchen, wird der Datentyp des Arrays auf object gesetzt. Arithmetische Operationen auf dem Array werden dann schwieriger, da NumPy die Arithmetik selbst nicht mehr ausführen kann.

>>> 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' 

Merkwürdigerweise kann die Reihenfolge der Argumente Swapping manchmal arbeiten:

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

In diesem zweiten Fall wird die Art des Das Ergebnis ist ein Python float, kein NumPy Array.

Das Update ist long Werte in NumPy Arrays zu vermeiden, Erstellen und float s anstatt:

>>> 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]) 

Wenn Sie einen Fehler machen bekommen, wie dies die Zukunft ist, das erste, was zu tun ist, das überprüfen dtype des zu multiplizierenden Arrays. Enthält es NumPy-Werte oder Python-Objekte?

+0

Guter Anruf! Meine Arrayvariable (y = np.square (np.add (np.divide (np.zeros (100), 42), (- 27) ** 40)) wie oben in meiner Frage definiert) hat den Typ 'object' (y.dtype) Leider bin ich nicht sicher, ob ich es zwingen kann, ein Float zu sein, wenn man bedenkt, dass es als Float beginnt und sich irgendwo auf dem Weg zu einem langen wirft. – Jason

+0

Es ist die Operation mit '(-27) ** 40 ', das ist das Problem. NumPy kann nicht direkt mit Python 's umgehen. Sie können jedoch 'np.array' verwenden, um ein NumPy-Array in ein anderes Array eines anderen Typs zu konvertieren. Zum Beispiel wird 'np.array (np.array (27 ** 40), dtype = np.float64)' ein Array vom Typ 'float64' zurückgeben. –

+0

Ja, ich konnte herausfinden, wo die Ints 27 und 40 in meinem Code erzeugt wurden, und sie als Floats darstellen. Für den Datensatz generiert np.arange int32. Die meisten numpy Funktionen funktionieren in Schwimmern einschließlich np.ones und np.zeros – Jason

-1

Ist das ein Quiz? Ich verstehe nicht, warum die Frage so verschleiert ist ... Alles läuft auf diese einfache Tatsache hinaus.

Bei

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

wir haben

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

Dies ist der Fehler ist (oder Feature, ich weiß es nicht) da es y.__mul__(x) == y.__rmul__(x) sein sollte (zumindest für diese besonderen Werte von x und y).

Python long nicht weiß, wie Multiplikation mit numpy.float64 zu handhaben (aber das ist richtig.)

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

So y*x-y.__mul__(x) auswertet und gibt das erwartete Ergebnis. Im Gegensatz x*y wird zuerst als x.__mul__(y) versucht (nicht implementiert, OK) als y.__rmul__(x) (nicht implementiert, aber ein Fehler.).

Wie bereits erwähnt, können wir nd.arrays von beliebigen Objekten haben, und alles wird klar.

bearbeiten

Dieser Fehler (wahrscheinlich ver in numpy 1.7.) Wurde korrigiert:

>>> 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

Warum wird dies heruntergeregelt? – Worthy7

+0

@ Worthy7 Keine Ahnung, warum meine Antwort wurde downvoted: IMHO es zeigt den numpy Bug verantwortlich für das unerwartete Verhalten, wie bestätigt durch https://github.com/numpy/numpy/issues/2930#issuecomment-12445232 (und nein, ich habe meine Antwort nicht geschrieben, nachdem ich dieses numme Problem gelesen habe.) –

Verwandte Themen