[PYTHON] Eine Geschichte, die die Leistung verbessern könnte, indem nur der Typ von numpy geändert wird

Einführung

Ich hatte die Gelegenheit, an der Verbesserung der Berechnungseffizienz von Numpy zu arbeiten. Dabei habe ich gelernt, wie wichtig dtype ist.

Als persönliches Memorandum hoffe ich natürlich, dass es jemandem nützlich sein wird. Was ich geschrieben habe, ist dieser Artikel.

[Zusatz] numpy ist ein numpy.array, das durch Anwenden der Methode ".values" auf die Datenrahmenversion von pandas read_csv erstellt wurde.

Leistung vorher und nachher

Wenn ich es schreibe,

  1. Führen Sie mehrere Matrixberechnungen der Größe (10.000.400) @ (4.550.000) durch.
  2. Nehmen Sie das Produktset von ihnen

Ich musste den Prozess machen, aber nur durch Ändern des D-Typs von Numpy Ich konnte es wie folgt verbessern. (Wie schrecklich es zuerst war ...)

Artikel before after
Verarbeitungszeit 70 Minuten 10 Minuten
Speicher verwendet Über 100 GB Über 30 GB

Im Folgenden werde ich schreiben, welche Art von Änderungen ich vorgenommen habe.

Was du getan hast

Über das Beschleunigen

** Setze dtype von numpy.array auf float32 oder float64 **

Es scheint, dass die Matrixberechnung von numpy [BLAS] verwendet (https://ja.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms). Es scheint also, dass dieser Typ gute Arbeit leisten wird, wenn es sich um den oben genannten Datentyp handelt. (Siehe den Artikel oben im Referenzlink)

In meinem Fall war es zuerst int, aber mit .astype (np.float32) Durch einfaches Ändern des Typs in float32 wurde die Verarbeitungszeit von 70 Minuten auf 10 Minuten reduziert! !!

[Zusatz] Nachdem ich über Nacht geschlafen und erneut gelesen hatte, dachte ich, dass die Erklärung der Situation unzureichend sei, deshalb werde ich sie ein wenig ergänzen.

Ursprünglich eine Hot-Codierung mit pd.get_dummies und dann mit .values Ich nahm numpy.ndarray heraus und berechnete es.

Bei dieser Methode lautet der Datentyp uint8, dies wird jedoch in float32 geändert. Ich konnte eine hohe Geschwindigkeit erreichen, indem ich sie änderte.

Der Code sieht so aus.

pd.get_dummies([Pandas-Serie]).astype(np.float32).values

Informationen zum Speichern von Speicher

** Wenn möglich, setzen Sie den Wert der Matrix auf den Bool-Wert **

Der oben erwähnte Floating-Prozess machte den Prozess explosiv, aber der Speicher wurde verbraucht. Früher habe ich mich gewehrt, indem ich oft unnötige Objekte "gelöscht" habe, aber es hat keine große Verbesserung gebracht.

Durch erneutes Halten des Berechnungsergebnisses in bool konnte ich jedoch viel Speicherplatz sparen. (Es scheint, dass der im Voraus reservierte Speicher zwischen dem Bool-Typ und dem Int-Float-Typ unterschiedlich ist.)

[Ergänzung] In Python gilt die folgende Beziehung zwischen "1/0" und "Wahr / Falsch".

true_false.png

Eine Matrix, die durch 1/0 dargestellt werden kann (zum Beispiel eine One-Hot-Codierungsmatrix), ist also Es kann auch als Bool-Wert ausgedrückt werden.

Und die passende Technik

Wie oben erwähnt, konnten wir die Effizienz allein durch die Kombination der beiden Punkte erheblich verbessern. Am Ende war der Prozessablauf so.

  1. Führen Sie eine Matrixberechnung mit dem Typ float32 durch ・ ArrayA = float32 matrix @ float32 matrix
  2. Konvertieren Sie das erhaltene Ergebnis in einen Bool-Typ ・ Mach einfach arrayA = (arrayA> = 1)
  3. Nehmen Sie das Produktset von ihnen ・result = arrayA | arrayB | arrayCMögen

Impressionen

Der Schwimmer scheint in verschiedenen Fällen verwendbar zu sein, aber ist der Bool begrenzt? Ich denke nicht, dass es angewendet werden kann, wenn das Ergebnis nicht durch 0/1 dargestellt werden kann.

Andere

Referenzlink

Recommended Posts

Eine Geschichte, die die Leistung verbessern könnte, indem nur der Typ von numpy geändert wird
Das Geheimnis der Zahl, die nur durch Anordnen von 1s gesehen werden kann - Die Anzahl der Wiederholungen und die mysteriöse Natur -
Die Geschichte von pep8 wechselt zu pycodestyle
Die Geschichte von Django, wie er eine Bibliothek erstellt, die vielleicht etwas nützlicher ist
Die Geschichte, dass unter Ubuntu kein 5-GHz-Bandzugangspunkt erstellt werden kann
Eine Geschichte, die den Aufwand für Betrieb / Wartung reduziert
Die Geschichte der durch gcrypto20 verursachten Nichtübereinstimmung von Hash Sum
Ein Hinweis, dass pyOSC int64 nicht erhalten hat
Eine Geschichte über die Änderung des Master-Namens von BlueZ
Die Geschichte, dass der Rückgabewert von tape.gradient () None war
Eine Geschichte, die die Lieferung von Nico Nama analysierte.
Listen Sie die Klassen auf, auf die ObjCClass verweisen kann
Die Geschichte von sys.path.append ()
Eine kleine süchtig machende Geschichte mit den Berechtigungen des von expdp angegebenen Verzeichnisses (für Anfänger)