[PYTHON] Checkliste, wie Sie vermeiden können, die Elemente des Numpy-Arrays mit for zu drehen

Wenn Sie das Element von numpy.array mit einer for-Anweisung drehen, sinkt die Ausführungsgeschwindigkeit erheblich.

Um dieses Problem zu umgehen, versuchen Sie es etwas schneller

--list Inklusive Notation --Verwenden Sie np.where, wenn die Bedingungen komplex sind --Verwenden Sie np.frompyfunc (aber seien Sie vorsichtig, wenn Sie es verwenden)

Ich habe das gelernt, also dieses Memorandum.

Notation der Listeneinbeziehung

Dies ist bereits überall geschrieben,

import numpy as np
a = np.array(range(10))
a2 = []
for x in a:
    a2.append(x*2)

Wenn du so etwas machst

a2 = [x*2 for x in a]

Die Geschichte, dass Sie es tun sollten. Es wird viel schneller zu erleben sein.

Verwenden Sie np.where, wenn die Bedingungen komplex sind

Zum Beispiel, wenn Sie mit Array a herumspielen möchten, aber die Bedingungen basierend auf den Elementen von Array b bestimmen möchten.

Betrachten Sie als Beispiel den Fall, in dem die Elemente des Arrays a verdoppelt werden, wenn die Elemente des Arrays b gerade sind, und die Elemente des Arrays a ansonsten verdreifacht werden.

Verwenden Sie np.where, um zu vermeiden, dass Sie einen Index wie C ++ verwenden möchten, und drehen Sie ihn mit for um.

import numpy as np
a = np.array(range(10))
print "a = ", a
b = a + 100
print "b = ", b

#Bei Verwendung des Index sieht es so aus
result1 = []
for i in range(10) :
    answer = a[i]*2 if b[i]%2 == 0 else a[i]*3
    result1.append(answer)
print np.array(result1)

# np.Wenn Sie where und die Funktion verwenden, können Sie in eine Zeile schreiben und es ist schnell

def func_double(x) :
    return x*2

def func_triple(x) :
    return x*3

result2 = np.where(b%2 == 0, func_double(a), func_triple(a))
print result2

Wie Sie kommentiert haben, können Sie, wenn es sich um eine Funktion dieses Grades handelt, die Funktion so einbetten, wie sie in der Listeneinschlussnotation enthalten ist.

(Ich persönlich mag es jedoch nicht, Funktionen direkt in die Listeneinschlussnotation einzubetten ... Es ist schwierig, verschiedene Dinge später zu ändern, ich vergesse, sie zu ändern, und ein junger Student mit einer Erstsprachenliste der Python-Generation Wenn Sie einen beschissenen langen Code in die enthaltene Notation schreiben, wird er scharf sein wie "Es ist wirklich schwer zu lesen !!!" (lacht)

Verwenden Sie np.frompyfunc (aber seien Sie vorsichtig, wenn Sie es verwenden)

Als ich etwas schneller nach etwas gesucht habe, habe ich die folgende Seite gefunden, also danke ich Ihnen, dass Sie es verwendet haben.

Der schnellste Weg, eine beliebige Funktion auf alle Elemente einer Python-Liste anzuwenden Python-Beschleunigungsexperiment-Kartenfunktion-

Verwenden wir also frompyfunc.

import numpy as np
# prepare input arrays
a = np.array(range(10))
print "array a is", a
b = a + 100
print "array b is", b

def addition(x, y):
    return x + y

np_addition = np.frompyfunc(addition, 2, 1)

print "print a + b using frompyfunc"
print np_addition(a, b)

print "print a + 1 using frompyfunc"
print np_addition(a, 1)

print "print 1 + b using frompyfunc"
print np_addition(1, b)

def subtruction(x, y):
    return x - y

np_subtruction = np.frompyfunc(subtruction, 2, 1)

print "using np.where and frompyfuncs"
result2 = np.where(b%2 == 0, np_addition(a, b), np_subtruction(a, b))
print result2

Die Argumente der von frompyfunc erstellten Universalfunktion sind das erste Funktionsobjekt, die zweite Anzahl von Argumenten und die dritte Anzahl von Rückgabewerten. Wenn Sie ein Array in das Argument einer universellen Funktion einfügen, wird das Ergebnis der Anwendung der Funktion auf jedes Element als Array zurückgegeben.

Was, wenn es so eine bequeme Sache gäbe, hätte ich sie schnell benutzen sollen. Selbst in Bezug auf die Erfahrung fühlt es sich etwa 30% schneller an als die Notation zur Aufnahme von Listen.

Da die Beschreibung falsch war, werde ich sie falten (ich werde sie falten, damit ich in Zukunft nicht wieder denselben Fehler mache)

Also, was ich überprüfen wollte, ist ** Ist es möglich, ein Array an das Argument der universellen Funktion zu übergeben, die von diesem frompyfunc erstellt wurde, und den Rest nur zu einem Float zu machen **? Die Geschichte.

Das Ergebnis ist überhaupt kein Problem! ~~ Mit anderen Worten, es gibt das berechnete Ergebnis zurück, während nur der Teil geändert wird, an dem das Array für jedes Element übergeben wird. ~~ ~~ Unabhängig davon, welches Argument als Array verwendet wird, wird es willkürlich entschieden. ~~

~~ Großartig! !! : grinsend: ~~

(Korrektur) Es war kein solches Problem, aber die Funktion, die die + und -Operatoren von numpy, die in den Additions- und Subtruktfunktionen verwendet wurden, einfach sowohl das Argumentarray als auch den Skalar akzeptierten (Korrektur). Tränen) Wenn Sie also in den Argumenten a und b eine einfache Liste anstelle von np.array einfügen, stirbt das obige Beispiel.

Deshalb habe ich den Teil gelöscht, den ich zuvor geschrieben habe. (Ende der Korrektur) </ div>

Frompyfunc hat jedoch einige Aspekte zu beachten, daher werde ich sie im Folgenden beschreiben.

Der dtype des Rückgabewerts (Arrays) von frompyfunc ist Object type!

Im Rückgabewert (numpy.array) der von frompyfunc erstellten Universalfunktion wird dtype zum Objekttyp. (Der Typ des darin enthaltenen Elements bleibt erhalten.)

Sie können sich normalerweise nur auf den Inhalt des Arrays beziehen. Wenn Sie jedoch versuchen, es beispielsweise mit numpy.histogramadd zu verwenden, werden Sie wütend, weil Sie nicht wie unten gezeigt vom Objekttyp in andere Typen umwandeln können.

...numpy/lib/function_base.py", line 1014, in histogramdd
    flatcount = bincount(xy, weights)
TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'

Um dies zu verhindern, können Sie den Rückgabewert numpy.array mit astype umwandeln, aber ...

result2 = np.where(b%2 == 0, np_addition(a, b).astype(np.float64), np_subtruction(a, b).astype(np.float64))

Das Problem ist, dass Astype eine Funktion ist, die ein neues Array erstellt und zurückgibt, sodass hier eine Kopie des Arrays erstellt wird. Abhängig von den Bedingungen kann diese Kopierzeit zu einer Ausführungsgeschwindigkeit führen, die sich nicht ändert, selbst wenn sie in der Listeneinschlussnotation aktiviert ist.

Informationen zur Verwendung der von np.where und frompyfunc zusammen erstellten Universalfunktion

In den letzten drei Zeilen des Beispiels wurde bestätigt, dass die von np.where und frompyfunc erstellte Universalfunktion zusammen verwendet werden kann. Aber anscheinend ist das ziemlich langsam. Es war ein Fehler im Programm, dass ich dachte, es wäre an einem Punkt zehnmal langsamer, aber es scheint, dass es ungefähr doppelt so langsam ist. Deshalb ist es schwierig, es in Situationen zu verwenden, in denen Geschwindigkeit wichtig ist.

Was ist schließlich das schnellste?

Im Fall eines einfachen Beispiels wie dem hier gegebenen denke ich, dass die Notation der Listeneinbeziehung fast dieselbe ist.

Es gibt jedoch Fälle, in denen Sie nicht möchten, dass die Inklusivnotation mit Funktionen und Bedingungen überfüllt ist und die Lesbarkeit beeinträchtigt wird, oder wenn Sie komplizierte Arbeiten ausführen möchten, die überhaupt nicht in einer Zeile geschrieben werden können. In einem solchen Fall wurde mir klar, dass das Schreiben von Code mit dem gesunden Menschenverstand der Sprache, die ich vor langer Zeit gelernt habe, unerwartet lange dauern würde.

Ich habe verschiedene Pläne ausprobiert, um den bereits geschriebenen Code zu beschleunigen, aber am Ende ist es am besten, das Argument der Funktion, die das Material ist, so umzuschreiben, dass es von Anfang an sowohl Skalar als auch Array akzeptiert und sich schnell bewegt Ich finde es gut.

Wenn Sie dies tun können, sieht die Kombination von np.where und vorhandenen Funktionen am saubersten und schnellsten aus, und Sie müssen mit frompyfunc keine universelle Funktion erstellen.

Da ich eine Person war, die zum ersten Mal Programme in Fortran und C ++ gelernt hat, habe ich eine Funktion geschrieben, die Daten einzeln verarbeitet, und ein Programm geschrieben, das nicht völlig aus der Idee heraus ist, sie durch Drehen mit for zu verarbeiten. Wenn Sie von Anfang an wissen, dass Sie numpy verwenden werden, hat numpy viele Funktionen, die Arrays schnell verarbeiten. Daher dachte ich, es wäre die richtige Antwort, es so zu gestalten, dass mehrere Datensätze von Anfang an als Matrix verarbeitet werden. Überlegen.

Recommended Posts

Checkliste, wie Sie vermeiden können, die Elemente des Numpy-Arrays mit for zu drehen
[Einführung in Python] So erhalten Sie den Datenindex mit der for-Anweisung
Ein Memo darüber, wie man das schwierige Problem der Erfassung von FX mit AI überwinden kann
So extrahieren Sie Bedingungen (erwerben Sie alle Elemente der Gruppe, die die Bedingungen erfüllen) für Gruppe für Gruppe
Ich möchte die Authentizität eines Elements eines numpy-Arrays bestimmen
Wie man die Anzahl der GPUs aus Python kennt ~ Hinweise zur Verwendung von Multiprocessing mit pytorch ~
So ändern Sie die Protokollstufe von Azure SDK für Python
So erhalten Sie die ID von Type2Tag NXP NTAG213 mit nfcpy
So überwachen Sie den Ausführungsstatus von sqlldr mit dem Befehl pv
Verwendung von Jupyter am Frontend von Spacon ITO
Wie nutzt man maschinelles Lernen für die Arbeit? 01_ Den Zweck des maschinellen Lernens verstehen
So aktualisieren Sie die Python-Version von Cloud Shell in GCP
Für diejenigen, die nicht wissen, wie man ein Passwort mit Jupyter auf Docker festlegt
So führen Sie den Übungscode des Buches "Profitable KI mit Python erstellen" in Google Colaboratory aus
So schneiden Sie den unteren rechten Teil des Bildes mit Python OpenCV
[Einführung in Python] So sortieren Sie den Inhalt einer Liste effizient mit Listensortierung
[Bilderkennung] Lesen des Ergebnisses der automatischen Annotation mit VoTT
Die zweite Nacht der Runde mit für
Die Geschichte des Versuchs, SSH_AUTH_SOCK mit LD_PRELOAD auf dem Bildschirm veraltet zu halten
Python: Tipps zum Anzeigen eines Arrays (einer Liste) mit einem Index (wie man herausfindet, welche Nummer ein Element eines Arrays ist)
Nützlich zum Ändern von Berechtigungen unter Linux! Wie man mit einer Hand bis zu 31 zählt.
So veröffentlichen Sie ein Blog auf Amazon S3 mit der statischen Blog-Engine "Pelican" für Pythonista
Wie sich die Referenz des Python-Arrays ändert, hängt vom Vorhandensein oder Fehlen von Indizes ab
Hinweise zum Implementieren des Schlüssels unter Amazon S3 mit Boto 3, Implementierungsbeispiel, Hinweise
[Python] So sortieren Sie nach dem N-ten M-ten Element eines mehrdimensionalen Arrays
[Python] So speichern Sie Bilder mit Beautiful Soup sofort im Web
Hinweis: So erhalten Sie den letzten Tag des Monats mit Python (hinzugefügt am ersten Tag des Monats)
So erhalten Sie mit Python eine Liste der Dateien im selben Verzeichnis
So berechnen Sie die Volatilität einer Marke
So verwenden Sie MkDocs zum ersten Mal
Strategie zur Monetarisierung mit Python Java
Sortieren Sie die Elemente eines Arrays, indem Sie Bedingungen angeben
So testen Sie den Friends-of-Friends-Algorithmus mit pyfof
So legen Sie Attribute mit Mock of Python fest
So implementieren Sie "named_scope" von RubyOnRails mit Django
So installieren Sie OpenGM unter OSX mit Macports
Einführung in Python mit Atom (unterwegs)
So vermeiden Sie BrokenPipeError mit PyTorchs DataLoader Hinweis
So erhalten Sie Elemente vom Typ Wörterbuch von Python 2.7
Wie man Kaldi mit JUST Corpus trainiert
So finden Sie die Korrelation für kategoriale Variablen
Wie man Zufallszahlen mit dem Zufallsmodul von NumPy macht
Lesen von Originaldaten oder externen Daten im Internet mit scikit-learn anstelle eines angehängten Datensatzes wie Iris
So legen Sie einen freigegebenen Ordner mit dem Host-Betriebssystem in CentOS7 auf Virtual BOX fest
Der erste Schritt des maschinellen Lernens ~ Für diejenigen, die versuchen möchten, mit Python zu implementieren ~
Wie identifiziere ich das Element mit der geringsten Anzahl von Zeichen in einer Python-Liste?
So vermeiden Sie die Cut-Off-Beschriftung des Diagramms, das vom Plotsystemmodul mit matplotlib erstellt wurde
Ich möchte die Standortinformationen von GTFS Realtime auf Jupyter zeichnen! (Mit Ballon)
Einfache Möglichkeit, 0 abhängig von der Anzahl der Ziffern vorangestellt [Python]
So zählen Sie die Anzahl der Vorkommen jedes Elements in der Liste in Python mit der Gewichtung
So legen Sie die Entwicklungsumgebung für jedes Projekt mit VSCode + Python-Erweiterung + Miniconda fest
Beim 15. Offline-Echtzeitversuch habe ich versucht, das Problem des Schreibens mit Python zu lösen
Wie man die Portnummer des xinetd-Dienstes kennt
Überlegen Sie, wie Sie Python auf Ihrem iPad programmieren können
Fügen Sie Attribute von Klassenobjekten mit einer for-Anweisung hinzu