问题:为什么我的Pandas的“应用”功能不能引用多个列?[关闭]
当将多个列与以下数据框一起使用时,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
回答 0
好像您忘记了''
字符串。
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
如果您只想计算(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
假设我们要对DataFrame df的列“ a”和“ b”应用add5函数
def add5(x):
return x+5
df[['a', 'b']].apply(add5)
回答 3
以上所有建议均有效,但如果您希望提高计算效率,则应利用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数组进行向量化将速度提高了近两个数量级。
回答 4
这与先前的解决方案相同,但是我已经在df.apply本身中定义了该函数:
df['Value'] = df.apply(lambda row: row['a']%row['c'], axis=1)
回答 5
我已经比较了上面讨论的所有三个。
使用值
%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个)