0
votes

Comment simplifier l'état des pandas

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 commentaires

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.


3 Réponses :


0
votes

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.


0 commentaires

0
votes

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"]


0 commentaires

2
votes

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)


0 commentaires