2014-09-08 3 views
3

Я использую pandas 13.0, и я пытаюсь создать новый colum, используя apply() и имя функции foo().Pandas - создать новый столбец с применением для float индексированных dataframe

Мой dataframe выглядит следующим образом:

df = pandas.DataFrame({ 
     'a':[ 0.0, 0.1, 0.2, 0.3], 
     'b':[10.0, 20.0, 30.0, 40.0], 
     'c':[ 1.0, 2.0, 3.0, 4.0] 
    }) 

df.set_index(df['a'], inplace=True) 

Так что мой dataframe является:

in: print df 

out: 
      a b  c 
     a 
     0.0 0.0 10.0 1.0 
     0.1 0.1 20.0 2.0 
     0.2 0.2 30.0 3.0 
     0.3 0.3 40.0 4.0 

Моя функция выглядит следующим образом:

def foo(arg1, arg2): 
    return arg1*arg2 

Теперь я хочу, чтобы создать имя столбца 'd', используя foo();

df['d'] = df.apply(foo(df['b'], df['c']), axis=1) 

Но я получаю следующее сообщение об ошибке:

TypeError: ("'Series' object is not callable", u'occurred at index 0.0') 

Как я могу использовать pandas.apply() с Foo() для индекса, которые сделаны из поплавка?

Благодаря

ответ

5

Проблема здесь состоит в том, что вы пытаетесь обработать этот рядам, но вы передаете серии, как заданы параметры, что неправильно вы могли бы сделать это следующим образом:

In [7]: 

df['d'] = df.apply(lambda row: foo(row['b'], row['c']), axis=1) 
df 
Out[7]: 
     a b c d 
a     
0.0 0.0 10 1 10 
0.1 0.1 20 2 40 
0.2 0.2 30 3 90 
0.3 0.3 40 4 160 

Лучший способ было бы просто назвать свою функцию прямой:

In [8]: 

df['d'] = foo(df['b'], df['c']) 
df 
Out[8]: 
     a b c d 
a     
0.0 0.0 10 1 10 
0.1 0.1 20 2 40 
0.2 0.2 30 3 90 
0.3 0.3 40 4 160 

преимущество описанного выше способа является то, что он vectorised и будет выполнять операцию на целый ряд довольно чем ряд за раз.

In [15]: 

%timeit df['d'] = df.apply(lambda row: foo(row['b'], row['c']), axis=1) 
%timeit df['d'] = foo(df['b'], df['c']) 
1000 loops, best of 3: 270 µs per loop 
1000 loops, best of 3: 214 µs per loop 

Не большая разница здесь, теперь сравните с 400000 строк ДФ:

In [18]: 

%timeit df['d'] = df.apply(lambda row: foo(row['b'], row['c']), axis=1) 
%timeit df['d'] = foo(df['b'], df['c']) 
1 loops, best of 3: 5.84 s per loop 
100 loops, best of 3: 8.68 ms per loop 

Итак, вы видите здесь ~ 672x скорость до.

+0

большое спасибо за ваш ответ. он работает сейчас. Кроме того, очень полезно сравнение скорости. Еще раз спасибо. – Julien

+0

Не беспокойтесь. Как правило, избегайте использования 'apply', если существует векторная операция, для базовых операций, таких как add/subtract/div и multiply, для поддержки на много порядков встроена поддержка операторов. – EdChum

Смежные вопросы