Ich arbeite mit der Pandas- Bibliothek und möchte einem Datenrahmen zwei neue Spalten hinzufügendf
mit n Spalten (n> 0) .
Diese neuen Spalten ergeben sich aus der Anwendung einer Funktion auf eine der Spalten im Datenrahmen.
Die anzuwendende Funktion lautet wie folgt:
def calculate(x):
...operate...
return z, y
Eine Methode zum Erstellen einer neuen Spalte für eine Funktion, die nur einen Wert zurückgibt, ist:
df['new_col']) = df['column_A'].map(a_function)
Also, was ich will und erfolglos versucht habe (*), ist so etwas wie:
(df['new_col_zetas'], df['new_col_ys']) = df['column_A'].map(calculate)
Was könnte der beste Weg sein, dies zu erreichen? Ich habe die Dokumentation ohne Ahnung gescannt .
** df['column_A'].map(calculate)
gibt eine Pandas-Serie zurück, wobei jedes Element aus einem Tupel z, y besteht. Wenn Sie versuchen, dies zwei Datenrahmenspalten zuzuweisen, wird ein ValueError erzeugt. *
Die Top-Antwort ist meiner Meinung nach fehlerhaft. Hoffentlich importiert niemand alle Pandas in ihren Namespace mit
from pandas import *
. Außerdem sollte diemap
Methode für diese Zeiten reserviert werden, wenn ein Wörterbuch oder eine Reihe übergeben wird. Es kann eine Funktion annehmen, aber dafür wirdapply
es verwendet.Wenn Sie also den obigen Ansatz verwenden müssen, würde ich ihn so schreiben
Es gibt hier eigentlich keinen Grund, zip zu verwenden. Sie können dies einfach tun:
Diese zweite Methode ist auch bei größeren DataFrames viel schneller
DataFrame mit 300.000 Zeilen erstellt
60x schneller als Reißverschluss
Vermeiden Sie im Allgemeinen die Verwendung von apply
Das Anwenden ist im Allgemeinen nicht viel schneller als das Durchlaufen einer Python-Liste. Lassen Sie uns die Leistung einer for-Schleife testen, um dasselbe wie oben zu tun
Das ist also doppelt so langsam, was keine schreckliche Leistungsregression ist, aber wenn wir das oben Gesagte zythonisieren, erhalten wir eine viel bessere Leistung. Angenommen, Sie verwenden ipython:
Direktes Zuweisen ohne zutreffen
Sie können noch größere Geschwindigkeitsverbesserungen erzielen, wenn Sie die direkten vektorisierten Operationen verwenden.
Dies nutzt die extrem schnellen vektorisierten Operationen von NumPy anstelle unserer Schleifen. Wir haben jetzt eine 30-fache Beschleunigung gegenüber dem Original.
Der einfachste Geschwindigkeitstest mit
apply
Das obige Beispiel sollte deutlich zeigen, wie langsam es sein
apply
kann, aber nur damit es besonders klar ist, schauen wir uns das grundlegendste Beispiel an. Lassen Sie uns eine Reihe von 10 Millionen Zahlen mit und ohne Anwendung quadrierenOhne Anwendung ist 50x schneller
quelle
applymap
für den Fall, wenn Sie für jedes Element des Datenrahmens eine bestimmte Funktion implementieren müssen?func(series)
anstelle von zu verwendenseries.apply(func)
ist, nur dann anwendbar ist, wenn die Funktion vollständig mit Operationen definiert ist, die sich sowohl für einen einzelnen Wert als auch für eine Serie ähnlich verhalten. Dies ist im Beispiel in der ersten Antwort der Fall, aber nicht in der Frage des OP, in der allgemeiner nach der Anwendung von Funktionen auf Spalten gefragt wird. 1/2DataFrame({'a': ['Aaron', 'Bert', 'Christopher'], 'b': ['Bold', 'Courageous', 'Distrusted']})
undcalc
ist:def calc(x): return x[0], len(x)
danntdf.a.apply(calc))
undcalc(tdf.a)
sehr unterschiedliche Dinge zurückgeben.