如何将Pandas的"apply"功能用于多个列?

And*_*ndy 228 python apply dataframe python-2.7 pandas

当使用具有以下数据帧的多个列时,我在使用Pandas应用函数时遇到一些问题

df = DataFrame ({'a' : np.random.randn(6),
                 'b' : ['foo', 'bar'] * 3,
                 'c' : np.random.randn(6)})
Run Code Online (Sandbox Code Playgroud)

以及以下功能

def my_test(a, b):
    return a % b
Run Code Online (Sandbox Code Playgroud)

当我尝试应用此功能时:

df['Value'] = df.apply(lambda row: my_test(row[a], row[c]), axis=1)
Run Code Online (Sandbox Code Playgroud)

我收到错误消息:

NameError: ("global name 'a' is not defined", u'occurred at index 0')
Run Code Online (Sandbox Code Playgroud)

我不明白这个消息,我正确地定义了这个名字.

我非常感谢你对这个问题的任何帮助

更新

谢谢你的帮助.我确实用代码做了一些语法错误,索引应该放''.但是我使用更复杂的功能仍然存在同样的问题,例如:

def my_test(a):
    cum_diff = 0
    for ix in df.index():
        cum_diff = cum_diff + (a - df['a'][ix])
    return cum_diff 
Run Code Online (Sandbox Code Playgroud)

谢谢

wai*_*kuo 361

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

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
Run Code Online (Sandbox Code Playgroud)

顺便说一下,在我看来,下面的方式更优雅:

In [53]: def my_test2(row):
....:     return row['a'] % row['c']
....:     

In [54]: df['Value'] = df.apply(my_test2, axis=1)
Run Code Online (Sandbox Code Playgroud)

  • @Andy关注[53-54]允许您应用更复杂的功能. (5认同)
  • `axis=1` 在这里很重要 (2认同)

her*_*rfz 31

如果您只想计算(列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
Run Code Online (Sandbox Code Playgroud)

  • 我知道,这只是一个示例,用于向多列应用函数时显示我的问题 (16认同)

小智 16

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

def add5(x):
    return x+5

df[['a', 'b']].apply(add5)
Run Code Online (Sandbox Code Playgroud)


Bla*_*ane 10

上面的所有建议都有效,但是如果你希望你的计算效率更高,你应该利用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)})
Run Code Online (Sandbox Code Playgroud)

示例1:循环使用pandas.apply():

%%timeit
def my_test2(row):
    return row['a'] % row['c']

df['Value'] = df.apply(my_test2, axis=1)
Run Code Online (Sandbox Code Playgroud)

最慢的运行时间比最快的长7.49倍.这可能意味着正在缓存中间结果.1000循环,最佳3:每循环481μs

示例2:使用pandas.apply()以下向量化:

%%timeit
df['a'] % df['c']
Run Code Online (Sandbox Code Playgroud)

最慢的运行时间比最快的时间长458.85倍.这可能意味着正在缓存中间结果.10000循环,最佳3:每循环70.9μs

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

%%timeit
df['a'].values % df['c'].values
Run Code Online (Sandbox Code Playgroud)

最慢的运行时间比最快的长7.98倍.这可能意味着正在缓存中间结果.100000个循环,最佳3:每循环6.39μs

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