TL;DR
Ich werde die Geschichte der Verwendung von apply () bei der Vorverarbeitung von Daten mit Pandas zusammenfassen.
http://pandas.pydata.org/pandas-docs/stable/ pandas ist eine Bibliothek, die die für die Datenanalyse in Python erforderlichen Methoden bereitstellt. Es kann eine Vielzahl von Daten verarbeiten, von Zeitreihendaten bis hin zu Datenreihen wie Tabellen, und kann mit hoher Geschwindigkeit aggregiert werden. In der heutigen Welt hört man oft den Fall "Daten mit Python analysieren".
Bei der Durchführung von Datenanalysearbeiten innerhalb von Moff verarbeiten wir die Daten häufig, nachdem wir die vorläufigen Daten extrahiert und dann vor Ort analysiert haben. Nachdem Sie die Datentabelle gezeichnet haben, die Sie am Ende erstellen möchten, müssen Sie bis dahin eine Vorverarbeitung ausführen.
Angenommen, Sie haben den folgenden Datensatz.
Nehmen wir danach an, Sie möchten "Ich möchte der Spalte eine neue Anzahl von Zeichen im Namen hinzufügen" vorverarbeiten.
Zu dieser Zeit war es besonders bei Praktikanten zu beobachten, die gerade mit dem Programmieren begannen, aber der folgende Vorverarbeitungscode wurde häufig in der Vorverarbeitung gesehen.
data['len'] = 0
for k, d in data['name'].iteritems():
data['len'][k] = len(d)
Dies reicht sicherlich für das Ausgabeergebnis aus, und ich denke, dass einige Datenzeilen mit Sicherheit so viel Zeit in Anspruch nehmen werden.
Lassen Sie uns nun mit apply () damit umgehen. apply () ist eine der Methoden, die in den Typen DataFrame und Series bereitgestellt werden. Die Ausdrücke DataFrame und Series verwenden außerdem jeden Wert im gruppierten DataFrame als Argument und den Rückgabewert der Funktion, die dem Argument von apply () zugewiesen wurde. Es kann Serien-, DataFrame- oder Skalarwerte zurückgeben.
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.apply.html https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.apply.html
Wenn Sie im vorherigen Beispiel eine Funktion erstellen, die len zurückgibt, sieht sie folgendermaßen aus.
def return_len(x)
return len(x)
data['len'] = data['name'].apply(return_len)
Wenn Sie den Lambda-Ausdruck (anonyme Funktion) kennen, können Sie auch Folgendes tun.
data['len'] = data['name'].apply(lambda x: len(x))
Ich denke, dass es in Bezug auf die Beschreibung relativ einfach sein wird.
Wie Sie vielleicht bemerkt haben, habe ich dieses Mal eine Funktion eingeführt, die das Ergebnis von len () durch Implementierung der Funktion zurückgibt. Wenn Sie sorgfältig darüber nachdenken, ist len () selbst auch eine Funktion, sodass Sie dies so tun können.
data['len'] = data['name'].apply(len)
Wenn es sich um einen einfachen Prozess handelt, kann er möglicherweise mit einer for-Schleife gelöst werden. Wenn Sie jedoch eine kompliziertere Vorverarbeitung in Betracht ziehen, ist es besser, eine Funktion daraus zu machen und sie mit apply () als oben anzuwenden, und Fehler usw. zu bemerken. Ich denke es wird billiger.
Im obigen Beispiel ist die Datenmenge gering, daher gibt es meines Erachtens einen Unterschied in der Verarbeitungsgeschwindigkeit. Daher werde ich das Ergebnis der Anwendung der Verarbeitung zeigen, die die Länge für zufällige Zeichenfolgendaten ausgibt. Die Überprüfungsumgebung ist wie folgt.
# of data | for loop | pandas.DataFrame.apply() |
---|---|---|
100 | 3.907sec | 0.079sec |
10000 | 415.032sec | 0.231sec |
100000 | 3100.906sec | 1.283sec |
Wie Sie sehen können, gibt es selbst bei ungefähr 100 Fällen einen Unterschied von ungefähr 3,8 Sekunden, und wenn die Anzahl der Fälle 10.000 oder 100.000 beträgt, wird der Unterschied in der Zeit, die zur Ausgabe des Ergebnisses erforderlich ist, enorm. Es ist klar, dass es besser ist, apply () zu verwenden, um ein schnelles Ergebnis zu erhalten, unabhängig von der Größe des Datasets oder der Vorverarbeitung.
Hier ist beispielsweise der Hauptteil von Apply of DataFrame https://github.com/pandas-dev/pandas/blob/5a7b5c958c6f004c395136f9438a1ed6c04861dd/pandas/core/frame.py#L6440
Wenn Sie frame_apply () folgen
https://github.com/pandas-dev/pandas/blob/5a7b5c958c6f004c395136f9438a1ed6c04861dd/pandas/core/apply.py#L26
Es scheint, dass etwas in einer Klasse namens FrameApply geschrieben ist.
https://github.com/pandas-dev/pandas/blob/5a7b5c958c6f004c395136f9438a1ed6c04861dd/pandas/core/apply.py#L56
Da wir get_result () auf frame_apply () aufrufen, werden wir den Prozess verfolgen.
https://github.com/pandas-dev/pandas/blob/5a7b5c958c6f004c395136f9438a1ed6c04861dd/pandas/core/apply.py#L144
Abhängig vom Parameter gibt es eine Verzweigung, aber es scheint, dass Folgendes aufgerufen wird, sofern kein optionales Argument angegeben wird.
https://github.com/pandas-dev/pandas/blob/5a7b5c958c6f004c395136f9438a1ed6c04861dd/pandas/core/apply.py#L269
Es scheint, dass libreduction.compute_reduction () den Berechnungskörper in apply_standard () ausführt. Danach scheinen apply_series_generator () und wrap_results () Ergebnisse zu liefern.
Es scheint, dass sich die Libreduktion in / _lib / reduction.pyx
befindet.
https://github.com/pandas-dev/pandas/blob/master/pandas/_libs/reduction.pyx
Anscheinend scheint es sich so zu verhalten, als würde man die Matrixdaten in Reducer durch numpy.ndarray.shape teilen und verschiedene Dinge von für i in range (self.n results):
tun.
https://github.com/pandas-dev/pandas/blob/5a7b5c958c6f004c395136f9438a1ed6c04861dd/pandas/_libs/reduction.pyx#L88
Von hier aus scheint es eine Geschichte über Numpy zu sein. Auch wenn Sie den obigen Code durchsuchen, Pandas Oben scheint es, dass es keine Punkte in der Berechnung gibt, also scheint es, dass die Verarbeitung auf Numpy entwickelt wurde. Denn schließlich gibt es auf dem obigen Reduzierer "res = self.f (chunk)" und den Punkt, den es speziell im Berechnungsprozess nach dem Anwenden der Funktion auf das ndarray von Numpy entwickelt hat. Ich konnte es nicht finden. Es gab eine Beschreibung, dass es separat in Chunk verarbeitet wurde, aber die Details der tatsächlichen Verarbeitung waren zum Zeitpunkt von "res = self.f (chunk)" der Funktionsanwendung und der Verarbeitung auf der Numpy-Seite danach unklar Es scheint mit abgeschlossen zu sein. In dem Maße, wie es auf der Straße gesagt wird, ist es sinnvoll hinzuzufügen, dass der Berechnungsprozess in Numpy schneller ist als der Berechnungsprozess in reinem Python allein.
Ich würde gerne etwas mehr wissen, aber da es umfangreich ist, mehr zu schreiben, werde ich eine weitere Gelegenheit nutzen, um die Verarbeitung in Numpy anzugeben. Wie auch immer, es wurde entschieden, dass es zumindest nicht auf Pandas war. (Obwohl noch unklar ist, ob es von der Sprachleistung abhängt oder durch Berechnungsverarbeitung entwickelt wird)
In Form einer Ableitung von apply () gibt es map () und applymap () in Series bzw. DataFrame. Auf den ersten Blick habe ich mich gefragt, was anders ist. Deshalb habe ich schnell gesucht und festgestellt, dass die Unterschiede in der folgenden StackOverFlow-Antwort zusammengefasst sind. https://stackoverflow.com/a/56300992/7649377
Wenn Sie nur die Hauptpunkte unterdrücken,
Ist das der Punkt?
Wenn ich das nächste Mal einen Artikel mit dieser Geschichte schreibe, werde ich Numpy lesen und ihn fangen. Vielen Dank.
Recommended Posts