2016-12-22 5 views
1

Я пытаюсь применить простую функцию к кадру данных pandas. Я хочу, чтобы достичь переменную «мишень», по формуле, определенной в «my_res», и добавить его в dataframeapply function pandas dataframe

import pandas as pd 
df = pd.DataFrame({'ID':['1','2','3'], 'v1': [0,2,3], 'v2':[1,4,5], 'v3':[11,43,52]}) 
print df 


def my_res (x,y,z): 
    target=(x*z)/y 
    return target 


df['target'] = df.apply(my_res('v1','v2','v3'),axis=1) 
print df 

и что если бы я имел формулу так:

def my_res (x,y,z): 
    target=(x*z)/y 
    check=target-z 
    return target 

#in this case I want to create 2 variable in the df 

ответ

1

Вы можете использовать lambda с именами столбцов:

df['target'] = df.apply(lambda x: my_res(x.v1,x.v2,x.v3),axis=1) 
print (df) 
    ID v1 v2 v3 target 
0 1 0 1 11  0.0 
1 2 2 4 43 21.5 
2 3 3 5 52 31.2 

Но лучше и быстрее будет использовать векторизованные решения с mul, div и sub :

df['target'] = df.v1 * df.v3 /df.v2 
print (df) 
    ID v1 v2 v3 target 
0 1 0 1 11  0.0 
1 2 2 4 43 21.5 
2 3 3 5 52 31.2 

df['target'] = df.v1.mul(df.v3).div(df.v2) 
print (df) 
    ID v1 v2 v3 target 
0 1 0 1 11  0.0 
1 2 2 4 43 21.5 
2 3 3 5 52 31.2 

Timings:

def my_res (x,y,z): 
    target=(x*z)/y 
    return target 

#[30000 rows x 4 columns]  
df = pd.concat([df]*10000).reset_index(drop=True) 
df['target'] = df.v1.mul(df.v3).div(df.v2) 
df['target1'] = df.apply(lambda x: my_res(x.v1,x.v2,x.v3),axis=1) 
print (df) 

In [290]: %timeit df.v1.mul(df.v3).div(df.v2) 
1000 loops, best of 3: 305 µs per loop 

In [291]: %timeit df.apply(lambda x: my_res(x.v1,x.v2,x.v3),axis=1) 
1 loop, best of 3: 1.66 s per loop 

In [292]: %timeit df.v1 * df.v3/df.v2 
1000 loops, best of 3: 562 µs per loop 
+0

спасибо, я добавил подробно обобщение на мой вопрос – progster

+0

Конечно, вы можете использовать 'ф.р. [ 'цель'] = df.v1.mul (df.v3) .div (df.v2) .sub (df.v3) ' ' df ['target'] = df.v1 * df.v3 /df.v2 - df.v3'. Решение 'apply' используется, если векторизованный подход невозможен. – jezrael

0

Там нет оснований использовать применять здесь. Простая векторная операция будет работать.

df.v1 * df.v3/df.v2