Wie der Titel sagt, nehme ich an, dass ich eine Zeichenfunktion schreiben möchte (vergessen wir jetzt Zeichen (0)), offensichtlich erwarten wir Zeichen (2) = 1 und Zeichen (Array ([- 2, -2,2] )) = Array ([- 1, -1,1]). Die folgende Funktion wird jedoch nicht funktionieren, da sie nicht mit numpy Arrays umgehen kann.
%Vor%Die nächste Funktion funktioniert auch nicht, da x kein Formelement hat, wenn es nur eine einzelne Zahl ist. Selbst wenn ein Trick wie y = x * 0 + 1 verwendet wird, wird y keine Methode [] haben.
%Vor%Auch mit der Idee aus einer anderen Frage ( Wie kann ich eine numpige Funktion erstellen, die ein numpy Array, ein iterables oder ein Skalar akzeptiert? ), die nächste Funktion wird nicht funktionieren, wenn x ein ist einzelne Zahl, weil in diesem Fall x.shape und y.shape just () sind und die Indizierung y unzulässig ist.
%Vor%Die einzige Lösung scheint zu sein, dass man zuerst entscheidet, ob x ein Array oder eine Zahl ist, aber ich möchte wissen, ob es etwas Besseres gibt. Das Schreiben von verzweigtem Code wäre umständlich, wenn Sie viele kleine Funktionen wie diese haben.
np.vectorize
kann verwendet werden, um das zu erreichen, wäre aber langsam, weil alles, was Sie tun, wenn Ihre dekorierte Funktion mit einem Array aufgerufen wird, die Array-Elemente durchläuft und die skalare Funktion auf jedes anwendet, dh keine numpy-Funktionen nutzt Geschwindigkeit.
Eine Methode, die ich für die Vektorisierung von Funktionen nützlich finde, wenn if-else np.choose
verwendet. :
Dies funktioniert, wenn x
entweder ein Skalar oder ein Array ist und schneller ist als eine Schleife im Python-Space.
Der einzige Nachteil der Verwendung von np.choose
ist, dass es nicht intuitiv ist, if-else Logik auf diese Weise zu schreiben, und der Code ist weniger lesbar. Wenn ich es verwende, füge ich Kommentare wie die oben genannten hinzu, um es dem Leser leichter zu machen, zu verstehen, was vor sich geht.
Hier ist eine Lösung:
%Vor% Dies sollte einen Wert des gleichen Typs wie die Eingabe zurückgeben. Zum Beispiel sign(42)
gibt 1
, sign(42.0)
gibt 1.0
. Wenn Sie es einem ndarray geben, funktioniert es wie np.sign
.
Im Allgemeinen können Sie davon ausgehen, dass Ihre Eingabe ein ND-Array ist. Wenn Sie versuchen, auf ein Attribut oder eine Methode zuzugreifen, die ein ndarray besitzt, aber Ihre Eingabe nicht, dann greifen Sie auf einen Skalartyp zurück. Verwenden Sie Ausnahmen, um dies zu implementieren. Zum Beispiel:
%Vor%