为什么我的熊猫不适用'函数引用多列工作?

时间:2013-05-03 07:25:49

标签: python python-2.7 pandas dataframe apply

当使用具有以下数据帧的多个列

时,我对Pandas应用功能有一些问题
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 

6 个答案:

答案 0 :(得分:333)

好像你忘记了字符串的''

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)

答案 1 :(得分:30)

如果您只想计算(列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

答案 2 :(得分:15)

假设我们要将函数add5应用于DataFrame df的列'a'和'b'

def add5(x):
    return x+5

df[['a', 'b']].apply(add5)

答案 3 :(得分:9)

上述所有建议都有效,但如果您希望计算效率更高,则应该利用numpy向量运算(as pointed out here)

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μs

示例2:使用pandas.apply()进行矢量化:

%%timeit
df['a'] % df['c']
  

最慢的跑步比最快跑的时间长458.85倍。这可以   表示正在缓存中间结果。 10000循环,最好的   3:每回路70.9μs

示例3:使用numpy数组进行矢量化:

%%timeit
df['a'].values % df['c'].values
  

最慢的跑步比最快跑的时间长7.98倍。这可以   表示正在缓存中间结果。 100000循环,最好的   3:每循环6.39μs

因此,使用numpy数组进行矢量化可将速度提高近两个数量级。

答案 4 :(得分:1)

这与先前的解决方案相同,但是我已经在df.apply本身中定义了该函数:

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

答案 5 :(得分:0)

我已经比较了上面讨论的所有三个。

使用值

%timeit df['value'] = df['a'].values % df['c'].values

每个循环139 µs±1.91 µs(平均±标准偏差,共运行7次,每个10000个循环)

无值

%timeit df['value'] = df['a']%df['c'] 

每个循环216 µs±1.86 µs(平均±标准偏差,共运行7次,每个循环1000次)

应用功能

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

每个循环474 µs±5.07 µs(平均±标准偏差,共运行7次,每个循环1000个)