Как использовать функцию 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 161

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 улучшила скорость почти на два порядка.

Это то же самое, что и предыдущее решение, но я определил функцию в df.применить себя:

df['Value'] = df.apply(lambda row: row['a']%row['c'], axis=1)