web-dev-qa-db-fra.com

Comment appliquer une fonction sur chaque ligne d'un cadre de données?

Je suis nouveau sur Python et je ne sais pas comment résoudre le problème suivant.

J'ai une fonction:

def EOQ(D,p,ck,ch):
    Q = math.sqrt((2*D*ck)/(ch*p))
    return Q

Disons que j'ai le dataframe

df = pd.DataFrame({"D": [10,20,30], "p": [20, 30, 10]})

    D   p
0   10  20
1   20  30
2   30  10

ch=0.2
ck=5

Et ch et ck sont des types float. Maintenant, je veux appliquer la formule à chaque ligne du cadre de données et la renvoyer sous la forme d'une ligne supplémentaire «Q». Un exemple (qui ne fonctionne pas) serait:

df['Q']= map(lambda p, D: EOQ(D,p,ck,ch),df['p'], df['D']) 

(retourne seulement les types 'map')

J'aurai davantage besoin de ce type de traitement dans mon projet et j'espère trouver quelque chose qui fonctionne.

11
Koen

Comme je ne sais pas ce que PartMaster est, ce qui suit devrait fonctionner:

def EOQ(D,p,ck,ch):
    p,D = Partmaster
    Q = math.sqrt((2*D*ck)/(ch*p))
    return Q
ch=0.2
ck=5
df['Q'] = df.apply(lambda row: EOQ(row['D'], row['p'], ck, ch), axis=1)
df

Si vous ne faites que calculer la racine carrée d'un résultat, utilisez la méthode np.sqrt, elle est vectorisée et sera beaucoup plus rapide:

In [80]:
df['Q'] = np.sqrt((2*df['D']*ck)/(ch*df['p']))

df
Out[80]:
    D   p          Q
0  10  20   5.000000
1  20  30   5.773503
2  30  10  12.247449

Horaires

Pour un 30k rangée df:

In [92]:

import math
ch=0.2
ck=5
def EOQ(D,p,ck,ch):
    Q = math.sqrt((2*D*ck)/(ch*p))
    return Q

%timeit np.sqrt((2*df['D']*ck)/(ch*df['p']))
%timeit df.apply(lambda row: EOQ(row['D'], row['p'], ck, ch), axis=1)
1000 loops, best of 3: 622 µs per loop
1 loops, best of 3: 1.19 s per loop

Vous pouvez voir que la méthode np est ~ 1900 X plus rapide

16
EdChum

Je suis d'accord avec la réponse d'EdChum. Une approche plus générale serait:

def RowWiseOperation(x):
    if x.ExistingColumn1 in x.ExistingColumn.split(','):
       return value1
    else:
       return value2

YourDataFrame['NewColumn'] = YourDataFrame.apply(RowWiseOperation, axis = 1)
0
Subspacian