English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

NumPy ufunc-generelle Funktionen

NumPy bietet zwei grundlegende Objekte, nämlich ndarray und ufunc-Objekte. Ufunc ist die Abkürzung für universal function, was bedeutet „allgemeine Funktion“. Es ist eine Funktion, die auf jedes Element eines Arrays angewendet werden kann.
Viele ufunc-Funktionen sind auf C-Sprachniveau implementiert, daher sind ihre Berechnungsgeschwindigkeiten sehr hoch.
Darüber hinaus sind ufun mehr flexibel als die Funktionen des mathematischen Moduls. Die Eingaben des mathematischen Moduls sind in der Regel Skalar, aber die Funktionen in NumPy können Vektoren oder Matrizen sein. Der Einsatz von Vektoren oder Matrizen kann den Einsatz von Schleifenverweisen vermeiden, was in der Maschinenlernen- und Deep-Learning-Welt sehr wichtig ist.

Warum sollte man ufuncs verwenden?

Ufunc wird verwendet, um Vektorisierung in NumPy zu implementieren, was schneller ist als das Iterieren über Elemente.
Sie bieten auch andere Methoden wie Reduzieren und Kombinieren, die für Berechnungen sehr nützlich sind.
Ufuncs akzeptieren auch andere Parameter, wie zum Beispiel:
where ist ein boolesches Array oder eine Bedingung, das verwendet wird, um zu bestimmen, wo die Operation durchgeführt werden soll.
dtype definiert den Rückgabetyp der Elemente.
Der Rückgabewert von out sollte in das Ausgabearray kopiert werden.

Einige häufig verwendete allgemeine Funktionen in NumPy
FunktionVerwendung
sqrt()Berechnung der Quadratwurzel einer serialisierten Datenreihe
sin(), cos()Trigonometrische Funktionen
abs()Berechnung des Absolutwerts einer serialisierten Datenreihe
dot()Matrixoperationen
log(), logl(), log2()Logarithmusfunktion
exp()Exponentialfunktion
cumsum(), cumproduct()Kumulative Summe, Produkt berechnen
sum()Summe einer serialisierten Datenreihe berechnen
mean()Berechnung des Durchschnittswerts
median()Berechnung des Median
std()Berechnung der Standardabweichung
var()Berechnung der Varianz
corrcoef()Berechnung des Korrelationskoeffizienten

Vergleich der Leistung von math und numpy Funktionen

import time
 import math
 import numpy as np
 x = [i * 0.001 for i in np.arange(1000000)
 start = time.clock()
 for i, t in enumerate(x):
 x[i] = math.sin(t)
 print("math.sin:", time.clock()) - start)
 x = [i * 0.001 for i in np.arange(1000000)
 x = np.array(x)
 start = time.clock()
 np.sin(x)
 print("numpy.sin:", time.clock()) - start)

Ergebnis der Ausführung:

math.sin: 0.5169950000000005
 numpy.sin: 0.05381199999999886

Daraus ergibt sich, dass numpy.sin etwa so schnell wie math.sin ist. 10 mal.

Vectorisierung

Die Umwandlung von Iterationsanweisungen in auf Vektoren basierende Operationen wird Vectorisierung genannt.
Da moderne CPUs für solche Operationen optimiert sind, ist die Geschwindigkeit schneller.
Zwei Listen von Elementen addieren:
list 1: [1, 2, 3, 4]
list 2: [4, 5, 6, 7]
Eine Methode ist es, beide Listen zu durchlaufen und die Elemente zu summieren.

Ohne ufunc können wir die eingebaute Python-Methode zip() verwenden:

x = [1, 2, 3, 4]
 y = [4, 5, 6, 7]
 z = []
 for i, j in zip(x, y):
   z.append(i + j)
 print(z)

Ergebnis der Ausführung:

[5, 7, 9, 11]

In diesem Fall bietet NumPy eine ufunc namens add(x, y),die das gleiche Ergebnis ausgibt. Mit Hilfe der ufunc können wir die Funktion add() verwenden:

import numpy as np
 x = [1, 2, 3, 4]
 y = [4, 5, 6, 7]
 z = np.add(x, y)
 print(z)

Ergebnis der Ausführung:

[5, 7, 9, 11]

Vergleich von Schleifen und Vektoroperationen

Nutzen Sie die eingebauten Funktionen der NumPy-Bibliothek von Python voll aus (Built-in Function),um die Vectorisierung der Berechnung zu realisieren, was die Laufzeit erheblich erhöhen kann. Die eingebauten Funktionen der NumPy-Bibliothek verwenden SIMD-Instruktionen. Der nachfolgende Vektorisierung ist erheblich schneller als die Berechnung mit Schleifen. Wenn ein GPU verwendet wird, ist die Leistung noch stärker, obwohl Numpy keine GPU unterstützt.
Sehen Sie sich den folgenden Code an:

import time
 import numpy as np
 x1 = np.random.rand(1000000)
 x2 = np.random.rand(1000000)
 ##Verwendung von Schleifen zur Berechnung des Skalarprodukts
 tic = time.process_time()
 dot = 0
 for i in range(len(x1)):
 dot+= x1[i]*x2[i]
 toc = time.process_time()
 print ("dot = " + str(dot) + ##for-Schleife-----Berechnungszeit = " + str(1000*(toc - tic)) + "ms")
 ##Verwendung von NumPy-Funktionen zur Berechnung des Skalarprodukts
 tic = time.process_time()
 dot = 0
 dot = np.dot(x1,x2)
 toc = time.process_time()
 print ("dot = " + str(dot) + "\n Verctor Version---- Berechnungszeit = " + str(1000*(toc - tic)) + "ms")

Ergebnis der Ausführung:

 dot = 250215.601995
 for-Schleife-----Berechnungszeit = 798.3389819999998ms
 dot = 250215.601995
 Verctor Version---- Berechnungszeit = 1.885051999999554ms