2014-10-08 16 views
5

Was effizient ist (Geschwindigkeit) Weg stückweise definierten Funktionen auf Numpy Array anwenden?Stückweise Funktionen auf Numpy Arrays

Nehmen wir zum Beispiel stückweise definierten Funktionen sind wie

For (1) : x<=2 f(x) = 2*x + x^2 
    (2) : x>2 f(x) = -(x^2 + 2) 

hier, was ich tat.

data = np.random.random_integers(5, size=(5,6)) 
print data 
np.piecewise(data, [data <= 2, data > 2], 
      [lambda x: 2*x + pow(2, x), 
       lambda x: -(pow(x, 2) + 2)]) 

data = 
[[4 2 1 1 5 3] 
[4 3 3 5 4 5] 
[3 2 4 2 5 3] 
[2 5 4 3 1 4] 
[5 3 3 5 5 5]] 
output = 
array([[-18, 8, 4, 4, -27, -11], 
     [-18, -11, -11, -27, -18, -27], 
     [-11, 8, -18, 8, -27, -11], 
     [ 8, -27, -18, -11, 4, -18], 
     [-27, -11, -11, -27, -27, -27]]) 

Gibt es eine effiziente Methode für kleinere Arrays, große Arrays, viele Funktionen usw.? Meine Sorge ist, dass Lambda-Funktionen verwendet werden. Nicht sicher, ob diese Numpy optimiert sind.

Antwort

3

In diesem Fall sollten Sie sich nicht über die Lambda-Ausdrücke betroffen sein: Numpy Optimierung ist über Call-Overhead reduziert, indem man Funktionen viele Werte in der gleichen Zeit im Batch zu bewerten. In jedem Aufruf np.piecewise jede Funktion in funclist (die Funktion Teile) wird genau einmal aufgerufen, wobei ein numpy Array bestehend aus allen Werten, bei denen die entsprechende Bedingung erfüllt ist. Somit werden diese Lambdas nummy-optimiert aufgerufen.

Ähnlich ist np.select (und np.where für genau zwei Teile). Der Aufruf-Overhead ist derselbe wie er auf die gleiche Weise vektorisiert wird, aber er wird alle Funktionen für alle Datenpunkte auswerten. Daher wird es langsamer als np.piecewise sein, insbesondere wenn die Funktionen teuer sind. In einigen Fällen ist es bequemer (kein Lambda), und man kann das Konzept leichter auf viele Variablen erweitern.

+0

Gute Antwort. Ein weiterer Vorteil der Verwendung von 'np.select()' oder 'np.where()' ist, dass Sie dann Zugriff auf das gesamte Array haben, wenn Sie die Berechnungen durchführen. Wenn Ihre Funktion von anderen Werten in der Eingabe abhängt (z. B. benachbarte Werte von jedem Punkt), ist dies nützlich. Aber im OP ist es egal, und 'np.piecewise()' ist gut. –