J'ai 3 colonnes dans DF[X,Y,Z]
; basé sur 3 colonnes, je dérive la colonne A. Voici l'expression qui dérive la colonne A.
DF.loc[(DF['X']<abs(DF['Y']-DF['Z']))&(DF['min']<DF['max']), 'A'] = abs(DF['Y']-DF['Z']) DF.loc[(DF['X']>abs(DF['Y']+DF['Z']))&(DF['min']<DF['max']), 'A'] = abs(DF['Y']+DF['Z']) DF['A'] = DF['A'].fillna(DF['X'])
Actuellement, je ne sais pas comment implémenter l'expression ci-dessus telle qu'elle est dans Pandas, mais je l'ai fait ci-dessous et cela fonctionne. Il semble que la logique ci-dessous soit plus complexe et redondante. Pourriez-vous s'il vous plaît me montrer comment modifier la logique ci-dessous en A = If X<YZ Then YZ Elsif X>Y+Z Then Y+Z Else X
A = If X<Y-Z Then Y-Z Elsif X>Y+Z Then Y+Z ELse X
Toute suggestion serait appréciée
3 Réponses :
Une façon de vous assurer que votre logique est appliquée et est facile à lire et à manipuler est de la réécrire dans une fonction, que vous .apply()
ensuite .apply()
au dataframe, ligne par ligne. Par exemple, vous pouvez effectuer les opérations suivantes (avec des données aléatoires):
import pandas as pd import numpy as np # let's generate some sample data df = pd.DataFrame(data=dict(X = np.random.randint(1, 50, 30), Y = np.random.randint(1, 50, 30), Z = np.random.randint(1, 50, 30))) def logic(row): """Function to encode your logic""" if row['X'] < row['Y'] - row['Z']: return row['Y']-row['Z'] elif row['X'] > row['Y'] + row['Z']: return row['Y'] + row['Z'] else: return row['X'] df['A'] = df.apply(logic, axis=1) # axis=1 ensures you are applying row-per-row
De cette façon, vous avez une fonction distincte où vous implémentez clairement la logique A = If X<YZ Then YZ Elsif X>Y+Z Then Y+Z ELse X
, et vous pouvez voir directement les conditions.
En général, je recommanderais d'appliquer une fonction - en utilisant axis = 1 vous donne accès à chaque colonne de chaque ligne.
Dans votre cas, cela devrait fonctionner:
DF.apply(getA, axis=1)
Ensuite, vous l'appliquez avec:
def getA(someRow): if someRow["X"] < (someRow["Y"] -someRow["Z"]): return someRow["Y"] - someRow["Z"] elif someRow["X"] > (someRow["Y"] + someRow["Z"]): return someRow["Y"] + someRow["Z"] else: return someRow["X"]
Utilisez numpy.select
. Ce serait le plus rapide en performance.
import numpy as np conditions = [(df.Y - df.Z) > df.X, (df.Y + df.Z) < df.X] choices = [df.Y - df.Z, df.Y + df.Z] df['A'] = np.select(conditions, choices, default=df.X)
Veuillez partager un exemple d'entrée de votre dataframe avec la sortie attendue pour une meilleure compréhension.
Le code me semble sonore, quel est le problème exactement?
Il n'y a pas de problème dans le code en tant que tel, car je suis un débutant en Python en supposant qu'il pourrait y avoir un moyen le plus simple d'écrire cette logique. Je cherche juste des suggestions d'experts.