1
votes

Pandas: création de colonnes conditionnelles

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?


0 commentaires

3 Réponses :


4
votes

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'])


6 commentaires

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.



1
votes

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)


1 commentaires

Merci! Donc, mon erreur s'est essentiellement résumée à un signe égal, haha!



0
votes

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'])


0 commentaires