2013-02-20 8 views
5

Ich habe versucht, vektorisieren (vereinbart, nicht die effizienteste Art und Weise, es zu tun, aber meine Frage ist eher auf der Dekorateur Verwendung) die folgende FunktionNumpy vectorize als Dekorateur mit Argumenten

@np.vectorize 
def diff_if_bigger(x, y): 
    return y - x if y > x else 0 

x = np.array([5.6, 7.0]) 
y = 8 

diff_if_bigger(x, y) 
# outputs array([2, 1]) which is not what I want 

EDIT: Nach dem Neustart von IPython war die Ausgabe in Ordnung.

Kann mir jemand erklären, warum das Ergebnis diff_if_bigger in ein Array von np.int tansformed wurde, selbst wenn das erste Argument x ist hier ein aray von np.float, im Gegensatz zu dem, was im doc ist ????

Jetzt will ich einen Schwimmer Ausgang zwingen, so habe ich diese

@np.vectorize('np.float') 
def diff_if_bigger(x, y): 
    return y - x if y > x else 0 
# Error !! 
# TypeError: Object is not callable. 

@np.vectorize(otypes='np.float') 
def diff_if_bigger(x, y): 
    return y - x if y > x else 0 
# Again error !! 
# TypeError: __init__() takes at least 2 arguments (2 given) 


@np.vectorize(otypes=[np.float]) 
def diff_if_bigger(x, y): 
    return y - x if y > x else 0 
# Still an error !! 
# TypeError: __init__() takes at least 2 arguments (2 given) 

By the way, auch diese

vec_diff = np.vectorize(diff_if_bigger, otypes=[np.float]) 

funktioniert nicht !!! So was ist los??

EDIT: In der Tat funktionierte letzteres nach dem Neustart von IPython.

Also nach meinen vorherigen zwei Bearbeitungen, ist meine Frage ist nun zweierlei:

1- Wie kann ich np.vectorize als Dekorateur mit Argumenten verwenden?

2- Wie kann ich den IPython-Zustand reinigen?

+0

@seberg, nein, du sagst Unsinn .. –

+0

Schau, du antwortest wirklich nicht spezifisch irgendwelche meiner Fragen .. Hast du sogar versucht, die Codebits zu laufen, die ich postete ??? Hast du dir die Vectorize-Hilfe angesehen ?? –

+0

Sorry, aber vielleicht solltest du bessere Fehlerbeschreibungen geben, es ist ein bisschen schwer so zu diagnostizieren. 1. Alle deine Beispiele funktionieren tatsächlich (aber die Dekoratoren geben einen Typ an, der das nicht kann). 2. Ihr erstes Beispiel könnte fehlschlagen, wenn Sie vor dieser Eingabe eine andere Eingabe gegeben haben. 3. Der letzte Vektorisierungsaufruf auf einer Funktion, die bereits vektorisiert ist, macht keinen Sinn, also ist das vielleicht dein ominöses "funktioniert nicht". – seberg

Antwort

7

Werke für mich:

>>> import numpy as np 
>>> @np.vectorize 
... def diff_if_bigger(x, y): 
...  return y - x if y > x else 0 
... 
>>> diff_if_bigger(np.array([5.6,7.0]), 8) 
array([ 2.4, 1. ]) 

Beachten Sie, dass np.vectorize als Dekorateur mit Ausnahme der einfachsten Fällen nicht wirklich bedeutete. Wenn Sie eine explizite otype angeben müssen, verwenden Sie das übliche Formular new_func = np.vectorize(old_func, otypes=...) oder verwenden Sie functools.partial, um einen Dekorator zu erhalten.

Hinweis zu, dass np.vectorize standardmäßig erhält seine Ausgangstyp, die Funktion auf dem ersten Argument aus der Auswertung:

Der Datentyp des Ausgangs des vectorized wird durch Aufruf der Funktion mit dem ersten Element bestimmt die Eingabe.

Also, sollten Sie float und zurück float geben, wenn Sie sicherstellen wollen, dass es float als Ausgabe dtype folgert (z else 0.0 verwenden und weitergeben y = 8.0).

+0

Meine numpy Version ist 1.6.1 .. und ich bekomme nicht das selbe Verhalten wie du, sondern den einen, den ich in meinem Post erwähnt habe. In meinem Fall ist die erste Eingabe x ein Array von 'np.float's, also warum bekomme ich am Ende ein Array von' np.int' Aber schlimmer, wie ich in meinem OP erwähnt habe, habe ich Fehler bekommen, auch wenn ich np.vectorize nicht als Dekorateur benutzt habe !! –

+1

ist es nicht die erste "Eingabe", die zählt, aber die erste "Ausgabe" und 0 ist kein float. – seberg

+0

@nneonneo Ich habe Angst, dass das Verhalten, das ich bekam, wegen des internen Status meiner IPython-Sitzung war. Aber dann kann ich nicht herausfinden, warum diese Sitzung bis zu dem Punkt korrumpiert wurde, wo sich das np.vectorize nicht wie in den Dokumenten angekündigt verhalten hat. –