Lesen Sie unseren Artikel über

.

Das Filtern von data mit ID == ‘string’ in Pandas sollten Sie vermeiden, da der scalar_compare-Operator zu Leistungsengpässen führt. Es gibt viele Möglichkeiten, dies zu umgehen, z.B. indem Sie Ihr Dataframe in ein Wörterbuch partitionieren und die betreffende ID als Schlüssel verwenden.

Einführung | String-Filter in Pandas

Die Vereinfachung der Hardware-Verwaltung durch die cloud-Lösungen führt dazu, dass wir uns mehr und mehr von den Problemen der Code-Optimierung abwenden.

The simplification of hardware management, brought by cloud solutions, pushes us more and more to turn away from the problems of code optimisation.

Aber die Vergrößerung und mehr Rechenleistung ist nicht immer die Lösung da es zu einer Eskalation der Kosten führt und die Rechenleistung nicht unendlich ist.

Als ich mich der Herausforderung stellte, mein gesamtes data-Präparat in einem einfachen Container unterzubringen, wurde mir schnell klar, dass ich mit dem Wissen um ein paar Tricks eine Menge erreichen kann, Die Optimierung Ihres Codes kann manchmal so einfach sein wie die Instanzierung einer größeren Instanz.

In diesem Artikel möchte ich auf eine einzige Codeänderung zurückkommen, die es mir ermöglicht hat, den Zeitaufwand für die Berechnung der Merkmale während der Entwicklungsphase eines Propensity-Modells drastisch zu reduzieren. Diese Änderung ist so allgemein, dass sie auch in vielen anderen Situationen angewendet werden kann.

Sie zielt nicht darauf ab, die optimalste Lösung zu sein, sondern versucht, eine schnelle Option zu sein, um die Berechnungszeit auf effiziente Weise zu verringern, im Sinne des Pareto-Prinzip.

Kontext

Während dieser Mission war ich für die Automatisierung des data-Vorbereitungsprozesses und der Vorhersage der von unserem Data-Wissenschaftlerteam entwickelten Modelle zuständig. Um den data-Ablauf zu vereinfachen, wurde täglich transaktionales data hochgeladen und musste eine erste Prüfung durchlaufen. Vorverarbeitung Schritt, gefolgt von einem zweiten Schritt der Merkmal Berechnung bevor Sie den letzten Schritt von Modell Vorhersage unter Verwendung des trainierten Modells.

The Feature computation phase is the one that took the longest time to execute: indeed many features were computed at the customer level

Die Berechnung von Merkmalen Phase ist diejenige, deren Ausführung die längste Zeit in Anspruch nahm: Tatsächlich wurden viele Merkmale auf Kundenebene berechnet, was zur wiederholten Ausführung einer überraschend zeitaufwendigen Zeile im Code führte:

which resulted in the recurrent execution of a surprisingly time-consuming line in the code :

Für diese einzelne Zeile wurde eine Zeit von 18 ms gemessen, was bedeutet, dass ich bei meinen 33.717 Clients, die ich täglich auswerten muss, etwa 10 Minuten reine Berechnungszeit pro Merkmal auf Kundenebene benötigte. Dank der Parallelisierung der Operation auf meinen 8 verfügbaren CPUs konnte ich diese Zeit auf 1 Minute und 16 Sekunden pro Merkmal reduzieren.

Da wir mit B2B data arbeiteten, war es notwendig, die Funktionen auf Kundenebene zu berechnen, da ein Kunde in Wirklichkeit ein Unternehmen mit manchmal mehreren Bestellungen pro Tag repräsentierte.

Experimentieren | String-Filter in Pandas

Nachdem ich ein wenig nachgeforscht habe, indem ich die %%prun magischen Befehl konnte ich die Quelle dieses Verarbeitungsengpasses identifizieren: die pandas._libs.ops.scalar_compare Operator, der in meiner Version von Pandas (1.3.1) unteroptimiert war.

Ersetzen Sie einfach dieses “==” Operator durch “isin”, was nicht sehr intuitiv ist, da ich eine einzelne Zeichenkette verglichen habe, habe ich die Rechenzeit bereits um das 2,5-fache geteilt, so dass ich von 18ms pro Operation auf 7,95ms kam.

Auf der Suche nach Optimierungsmöglichkeiten bin ich auf eine Stackoverflow Beitrag zur Förderung der Verwendung von Typ kategorisch um die Operation weiter zu verbessern.

Diese letzte Implementierung ermöglichte es mir, die Rechenzeit auf mehr als 36 Mal. Ich konnte jedoch eine Nuance bei diesem Trick beobachten, denn der Kategorietyp verhält sich nicht bei allen Operationen wie ein klassischer str (siehe Beispiel unten bei der Verwendung von .groupby() in Pandas), so dass ich es an einer Stelle wieder in str umwandeln musste.

Hypothese

Aber warum ist das so? Wie kann eine einfache == Operation zwischen zwei Strings benötigt mehr Zeit als eine isin() Operation, die Listen vergleicht, oder eine kategorisch eine ?
Nun, um die erste Frage zu beantworten, müssten wir auf jeden Fall den Code ausgraben, der hinter der Ausführung von scalar_compare der hauptsächlich Cython verwendet, und vergleichen Sie ihn mit dem Code hinter dem isin() Methode.

Glücklicherweise scheint die Antwort auf den zweiten Teil eher intuitiv zu sein: Wenn wir zwei String-Werte vergleichen, vergleichen wir ein unendliche Anzahl von Möglichkeiten zusammen, während beim Vergleich zweier Kategorien die Anzahl der Optionen wird festgelegt durch die verschiedenen einzigartigen Kategorien, die es gibt. Es scheint viel Es ist einfacher, zwei Entitäten zu vergleichen, wenn die Anzahl der Optionen festgelegt ist..

Da mein Optimierungsdrang noch immer nicht gestillt war, beschloss ich, einen Schritt zurück von der bisherigen Methode zu gehen. Ich habe mir einen neuen Ansatz ausgedacht: Partitionierung meines Data-Frame in ein Wörterbuch die ich dann zum Filtern meiner Kunden bei der Berechnung meiner Merkmale verwende.
In Bezug auf den Code bedeutete dies einfach die folgenden Zeilen:

kunden_liste = list(df.ID_Customer.unique()) df_dict = {elem: df[df.ID_Customer == elem] for elem in customers_list}

Die Erstellung dieses Wörterbuchs hat mich 32 Sekunden Rechenzeit gekostet, aber mit diesem partitionierten Data-Frame konnte ich meine data nun in wenigen Nanosekunden filtern.

Fazit | String-Filter in Pandas

Nachdem ich ein paar Stunden in der Experimentierphase verbracht hatte, war ich mit dem Ergebnis zufrieden:

After spending a couple of hours in the experimentation phase, I was happy with the result :

Die anfängliche Rechenzeit pro Kundenfilterung wurde nun geteilt 348 000 mal, ausgehend von 18ms bis 51.7ns, oder von 10min bis 2.65ms pro Merkmal, das in meinem Fall unter Berücksichtigung der für die Partitionierung aufgewendeten Zeit berechnet wurde.

Immediately, the impact of this small change allowed me to reduce the calculation time of my complete Feature computation phase by 90%, from 40'49" to 7'27".

Die Auswirkungen dieser kleinen Veränderung erlaubten mir sofort die Berechnungszeit meiner kompletten Feature-Berechnungsphase um 90% reduzieren, von 40’49” auf 7’27”. Mit Hilfe einer CO2eq-Schätzmethode, die ich in meinem nächsten Artikel näher erläutern werde, ist diese Änderung mindestens 170$/Jahr + 22kgCO2/Jahr eingespart und möglicherweise noch viel mehr mit der wachsenden Kundenliste und der Einführung des Projekts in anderen Ländern.

Medium Blog von Artefact.

Dieser Artikel wurde ursprünglich veröffentlicht auf Medium.com.
Folgen Sie uns auf unserem Medium Blog !