J'essaie de créer la colonne C , en fonction des valeurs des colonnes A et B compte tenu des conditions suivantes:
df['C'] = df.apply(lambda x (x['A'] * x['B)'] if x['A'] < 5000 else x = x['A']),axis=1)
Ce qui suit donne une erreur de syntaxe :
if A < 5000: C = A * B else: C = A
À quelle distance suis-je?
3 Réponses :
Utilisez numpy.where code vectorisé >
:
N = 100000 data = np.asarray([np.random.rand(N).tolist(), list(range(N))]).T df = pd.DataFrame(data, columns=['A', 'B']) In [59]: %timeit df['C'] = np.where(df['A'] < 5000, df['A'] * df['B'], df['A']) 1.29 ms ± 23.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) In [60]: %timeit df['C'] = df.apply(lambda x: x.A * x.B if x.A > 0.5 else x.A, 1) 3.32 s ± 374 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Performances :
np.random.seed(2019) N = 1000 data = np.asarray([np.random.rand(N).tolist(), list(range(N))]).T df = pd.DataFrame(data, columns=['A', 'B']) In [56]: %timeit df['C'] = np.where(df['A'] < 5000, df['A'] * df['B'], df['A']) 536 µs ± 47.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) In [57]: %timeit df['C'] = df.apply(lambda x: x.A * x.B if x.A > 0.5 else x.A, 1) 30.9 ms ± 597 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
df['C'] = np.where(df['A'] < 5000, df['A'] * df['B'], df['A'])
Très appréciée!
.where est nettement plus efficace que l'application de lambda. Merci!
Oh, c'est en effet une grande différence de performances. Je ne savais pas que c'était que lent.
@displayname - oui, le problème est que apply
sont des boucles sous le capot.
@jezrael je vois - merci pour l'info. J'envisagerai cela à l'avenir :) Donc, chaque fois que je peux éviter postuler
, je devrais l'éviter, je suppose.
@displayname - Cela dépend, s'il existe une alternative vectorisée mieux vaut éviter, si elle n'existe pas besoin d'elle ou d'une autre solution de boucle.
Je pense que vous voudriez quelque chose comme
import pandas as pd import numpy as np N = 10 data = np.asarray([np.random.rand(N).tolist(), list(range(N))]).T df = pd.DataFrame(data, columns=['A', 'B']) df['C'] = df.apply(lambda x: x.A * x.B if x.A > 0.5 else x.A, 1)
Exemple complet:
df['C'] = df.apply(lambda x: x.A * x.B if x.A > 0.5 else x.A, 1)
Merci! Donc, mon erreur s'est essentiellement résumée à un signe égal, haha!
Je suis sûr que les solutions fournies avant celle-ci sont meilleures mais je l'ai résolue d'une troisième manière. L'ensemble de données est plutôt petit, donc ça va faire pour le moment.
multiplier = df ['A'] * df ['B'] df ['C'] = multiplier.where (df ['A'] <5000, autre = df ['A'])