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.