Как использовать функцию Pandas 'apply' для нескольких столбцов?
у меня есть некоторые проблемы с функцией Pandas apply, при использовании нескольких столбцов со следующим фреймом данных
df = DataFrame ({'a' : np.random.randn(6),
'b' : ['foo', 'bar'] * 3,
'c' : np.random.randn(6)})
и следующая функция
def my_test(a, b):
return a % b
когда я пытаюсь применить эту функцию :
df['Value'] = df.apply(lambda row: my_test(row[a], row[c]), axis=1)
я получаю сообщение об ошибке:
NameError: ("global name 'a' is not defined", u'occurred at index 0')
Я не понимаю это сообщение, Я правильно определил имя.
Я был бы очень признателен за любую помощь в этом выпуск
обновление
Спасибо за вашу помощь. Я сделал некоторые синтаксические ошибки с кодом, то индекс должен быть поставлен ". Однако у меня все та же проблема с использованием более сложной функции, такой как:
def my_test(a):
cum_diff = 0
for ix in df.index():
cum_diff = cum_diff + (a - df['a'][ix])
return cum_diff
спасибо
5 ответов:
кажется, вы забыли
''
строки.In [43]: df['Value'] = df.apply(lambda row: my_test(row['a'], row['c']), axis=1) In [44]: df Out[44]: a b c Value 0 -1.674308 foo 0.343801 0.044698 1 -2.163236 bar -2.046438 -0.116798 2 -0.199115 foo -0.458050 -0.199115 3 0.918646 bar -0.007185 -0.001006 4 1.336830 foo 0.534292 0.268245 5 0.976844 bar -0.773630 -0.570417
кстати, на мой взгляд, более элегантен следующий способ:
In [53]: def my_test2(row): ....: return row['a'] % row['c'] ....: In [54]: df['Value'] = df.apply(my_test2, axis=1)
Если вы просто хотите вычислить (столбец a) % (столбец b), вам не нужно
apply
, просто сделайте это прямо:In [7]: df['a'] % df['c'] Out[7]: 0 -1.132022 1 -0.939493 2 0.201931 3 0.511374 4 -0.694647 5 -0.023486 Name: a
допустим, мы хотим применить функцию add5 к столбцам 'a' и ' b ' фрейма данных df
def add5(x): return x+5 df[['a', 'b']].apply(add5)
все предложения выше работают, но если вы хотите, чтобы ваши вычисления были более эффективными, вы должны воспользоваться векторными операциями numpy (как указано здесь).
import pandas as pd import numpy as np df = pd.DataFrame ({'a' : np.random.randn(6), 'b' : ['foo', 'bar'] * 3, 'c' : np.random.randn(6)})
Пример 1: цикл с
pandas.apply()
:%%timeit def my_test2(row): return row['a'] % row['c'] df['Value'] = df.apply(my_test2, axis=1)
самый медленный пробег занял в 7,49 раза больше времени, чем самый быстрый. Это могло бы означает, что промежуточный результат кэшируется. 1000 петель, лучше 3: 481 МКС на петлю
Пример 2: векторизовать с помощью
pandas.apply()
:%%timeit df['a'] % df['c']
самый медленный пробег занял в 458,85 раза больше времени, чем самый быстрый. Это могло бы означает, что промежуточный результат кэшируется. 10000 циклов, лучше 3: 70,9 МКС на петлю
Пример 3: векторизация с использованием массивов numpy:
%%timeit df['a'].values % df['c'].values
самый медленный пробег занял в 7,98 раза больше времени, чем самый быстрый. Это могло бы означает, что промежуточный результат кэшируется. 100000 циклов, лучшей часть 3: 6.39 МКС на петля
таким образом, векторизация с использованием массивов numpy улучшила скорость почти на два порядка.