249

当使用具有以下数据框的多个列时,我的 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 
4

6 回答 6

394

似乎你忘记了''你的字符串。

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)
于 2013-05-03T08:40:31.377 回答
33

如果你只想计算 (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
于 2013-05-03T07:56:43.013 回答
18

假设我们想将函数 add5 应用于 DataFrame df 的“a”和“b”列

def add5(x):
    return x+5

df[['a', 'b']].apply(add5)
于 2017-11-12T19:18:06.520 回答
11

上述所有建议都有效,但如果您希望计算效率更高,您应该利用 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 µ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 数组进行矢量化将速度提高了近两个数量级。

于 2018-04-27T21:14:48.220 回答
3

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

df['Value'] = df.apply(lambda row: row['a']%row['c'], axis=1)
于 2018-09-30T04:47:45.067 回答
2

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

使用价值观

%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 个循环)

于 2019-02-17T03:53:41.110 回答