在pandas中,apply()函数的使用方法?

2023年2月16日13:44:50在pandas中,apply()函数的使用方法?已关闭评论

apply()函数常用于对DataFrame进行行迭代或者列迭代,它的axis的含义与统计聚合函数的axis的含义一致。apply()的参数往往是一个以序列为输入的函数,例如,对于mean(),使用apply()可以写出:

In [79]:   df_demo = df[['Height', 'Weight']]
           def my_mean(x):
               res = x.mean()
               return res
           df_demo.apply(my_mean)
Out[79]:   Height    163.218033
           Weight     55.015873
           dtype: float64

对于简单的函数,可以利用Lambda表达式使得书写简洁,如下代码中的x就指代被调用的df_demo表中逐个输入的序列:

In [80]:   df_demo.apply(lambda x:x.mean())
Out[80]:   Height   163.218033
           Weight    55.015873 
           type: float64

若指定axis=1,那么每次传入函数的就是由行元素组成的Series,其结果与2.3.2节例子中的逐行均值的结果一致。

In [81]:   df_demo.apply(lambda x:x.mean(), axis=1).head()
Out[81]:   0    102.45
           1    118.25
           2    138.95
           3     41.00
           4    124.00
           dtype: float64

这里再举一个例子:mad()返回的是一个序列中元素偏离该序列均值的绝对值大小的均值,例如序列[1,3,7,10]中,均值为5.25,每一个元素偏离的绝对值为[4.25,2.25,1.75,4.75],这个偏离序列的均值为3.25。现在利用apply()、mad()计算身高和体重的指标:

In [82]:   df_demo.apply(lambda x:(x-x.mean()).abs().mean())
Out[82]:   Height     6.707229
           Weight    10.391870
           dtype: float64
In [83]:   df_demo.mad()
Out[83]:   Height     6.707229
           Weight    10.391870 
           dtype: float64

既然apply()如此强大,是不是就意味着其他的函数都没有用武之地,它们都可以用自定义函数来替换呢?答案是否定的,apply()的自由性是牺牲性能换来的。当apply()中迭代的行或列的数量较多时,运算时间明显变长。仍然以计算身高和体重的均值这一过程为例,我们来分别比较在200行数据样本下使用apply()和使用内置函数的性能差异:

In [84]:   %timeit -n 100 -r 7 df_demo.apply(lambda x:x.mean(), axis=1)
Out[84]:   16.6ms ± 347 µs per loop (mean ± std.dev.of 7 runs, 100 loops each) 
In [85]:   %timeit df_demo.mean(1) 
Out[85]:    182µs ± 10.7 µs per loop (mean ± std.dev.of 7 runs, 100 loops each)

注解

在Jupyter中可以使用%timeit来估计一行代码所运行的时间,其中参数-r表示运行的轮数(runs),参数-n表示每一轮该代码运行的次数(loops)。


从结果可以看到,在这个例子中它们竟存在高达约100倍的时长差距,这样的结果显然是我们不愿看见的。从另一方面说,我们应该在何时使用apply()?笔者认为只有当不存在内置函数能够解决当下的计算问题且apply()的迭代次数较少时,我们才考虑使用apply()来辅助完成计算任务。总之,在apply()的“诱惑”前,我们应当保持谨慎。

  • A+
所属分类:R
  • 版权声明:本篇文章(包括图片)来自网络,由程序自动采集,著作权(版权)归原作者所有,如有侵权联系我们删除,联系方式(QQ:452038415)。