Wie kann ich eine numpige Funktion erstellen, die ein numpy Array, einen iterablen oder einen Skalar akzeptiert?

9

Angenommen, ich habe Folgendes:

%Vor%

aber ich möchte es so ändern, dass es entweder ein numpy-Array, ein iterables oder einen Skalar annehmen kann, und das Argument in ein numpy-Array hochstufen und jedem Element 1 hinzufügen.

Wie könnte ich das tun? Ich nehme an, ich könnte die Argumentklasse testen, aber das scheint eine schlechte Idee zu sein. Wenn ich das tue:

%Vor%

es funktioniert ordnungsgemäß auf Arrays oder iterables aber nicht Skalaren. Das Problem hierbei ist, dass numpy.array(x) für Skalar x ein seltsames Objekt erzeugt, das in einem numply Array enthalten ist, aber kein "reales" Array ist; Wenn ich einen Skalar hinzufüge, wird das Ergebnis zu einem Skalar degradiert.

    
Jason S 29.09.2012, 13:31
quelle

3 Antworten

9

Sie könnten es versuchen

%Vor%

np.asarray(x) ist das äquivalent np.array(x, copy=False) , was bedeutet, dass ein Skalar oder iterable wird zu einem ndarray umgewandelt werden, aber wenn x bereits ein ndarray , seine Daten nicht kopiert werden.

Wenn Sie übergeben einen skalar und wollen ein ndarray als Ausgang (keinen Skalar), können Sie:

%Vor%

Das Argument ndmin=1 erzwingt, dass das Array mindestens eine Dimension hat. Verwenden Sie ndmin=2 für mindestens 2 Dimensionen und so weiter. Sie können auch ihr Äquivalent np.atleast_1d (oder np.atleast_2d für die 2D-Version ...)

    
Pierre GM 29.09.2012, 13:38
quelle
1

Die Antwort von Pierre GM ist großartig, solange Ihre Funktion ausschließlich ufuncs (oder etwas Ähnliches) verwendet, um die Eingabewerte implizit zu durchlaufen. Wenn Ihre Funktion über die Eingaben iterieren muss, tut np.asarray nicht genug, weil Sie nicht über einen NumPy-Skalar iterieren können:

%Vor%

Wenn Ihre Funktion über die Eingabe iterieren muss, funktioniert etwa Folgendes: np.atleast_1d und np.squeeze (siehe Array Manipulationsroutinen - NumPy Manual ). Ich habe ein Argument aaout ("Always Array OUT") eingefügt, damit Sie angeben können, ob skalare Eingänge für die Ausgabe von Einzelelement-Arrays verwendet werden sollen. Es könnte fallen gelassen werden, wenn es nicht benötigt wird:

%Vor%

Natürlich sollten Sie zur Potenzierung nicht explizit wie hier iterieren, aber eine komplexere Operation kann nicht mit NumPy ufuncs ausgedrückt werden. Wenn Sie not nicht iterieren müssen, aber eine ähnliche Kontrolle darüber haben möchten, ob Skalareingaben Einzelelement-Array-Ausgaben erzeugen, könnte die Mitte der Funktion einfacher sein, aber die Rückkehr muss mit np.atleast_1d umgehen:

%Vor%

Ich vermute, dass in den meisten Fällen das Flag aaout nicht notwendig ist und dass Sie immer skalare Ausgaben mit skalaren Eingaben wünschen. In solchen Fällen sollte die Rückgabe nur lauten:

%Vor%     
Tom Loredo 20.03.2018 00:00
quelle
0

Das ist eine alte Frage, aber hier sind meine zwei Cent.

Obwohl die Antwort von Pierre GM großartig funktioniert, hat sie den - vielleicht unerwünschten - Nebeneffekt der Umwandlung von Skalaren in Arrays. Wenn Sie das wollen / brauchen, hören Sie auf zu lesen; ansonsten, mach weiter. Während dies in Ordnung sein könnte (und ist wahrscheinlich gut für lists und andere iterables , um eine np.array zurückzugeben), könnte argumentiert werden, dass es für Skalare einen Skalar zurückgeben sollte. Wenn das das gewünschte Verhalten ist, warum nicht folgen Sie Pythons EAFP Philosophie. Dies ist, was ich normalerweise tue (ich habe das Beispiel geändert, um zu zeigen, was passieren könnte, wenn np.asarray einen "Skalar" zurückgibt):

%Vor%

Mir ist klar, dass es viel ausführlicher ist als die Antwort von Pierre GM, aber wie gesagt, diese Lösung wird einen Skalar zurückgeben, wenn ein Skalar übergeben wird oder ein np.array ein Array ist oder iterierbar ist.

    
jorgeh 03.10.2015 00:37
quelle

Tags und Links