apply()函数在pandas众多函数中,堪称神一样的存在,在数据分析批量处理dataframe数据时,好用到爆,这里简要叙述一下apply的几种使用方法及技巧。
一、apply函数中的参数
DataFrame.apply(func: 'AggFuncType', axis: 'Axis' = 0,raw: 'bool' = False,result_type=None,args=(),**kwargs)
参 数:
func :function,应用到每行或每列的函数。
axis:{0 or 'index', 1 or 'columns'},默认 0 ,控制函数应用的数据轴。
0 or index:对每一列数据应用函数。
1 or columns:对每一行数据应用函数。
raw:bool,默认 False,控制行或列是以Series还是ndarray对象传递。
False:将每一行或每一列作为一个Series传递给函数;
True:传递的函数将接收ndarray 对象。如果你只是应用一个 NumPy 还原函数,这将获得更好的性能。
result_type:{'expand', 'reduce', 'broadcast', None},默认为 None, 只有在axis=1时才会发挥作用。
expand :列表式的结果将被转化为列。
reduce:如果可能的话,返回一个Series,而不是展开类似列表的结果。这与 expand 相反。
broadcast : 结果将被广播到 DataFrame 的原始形状,原始索引和列将被保留。
默认行为(None)取决于应用函数的返回值:类似列表的结果将作为这些结果的 Series 返回。但是,如果应用函数返回一个 Series ,这些结果将被扩展为列。
args : tuple 除了数组/序列之外,要传递给函数的位置参数。
**kwds: 作为关键字参数传递给函数的附加关键字参数。
二、简单应用
DataFrame['columnName'].apply(function)
直接在apply中运用函数,可以使用python内置函数也可以使用自定义函数,如data.loc[:,'A'].apply(str),将A列所有数据转为字符串;data.loc[:,'A'].apply(float),将A列所有数据转为浮点型等等;
所有示例使用以下数据集:
data = pd.DataFrame([[1,2],[3,4],[5,6],[7,8]],columns=['A','B'])
演示数据集
自定义函数如果仅包含需要处理的默认参数,与内置函数应用方法相同,直接放入函数名即可,如:
def fun1(num):
if num>3:
return 1
else:
return 0
data.loc[:,'A'].apply(fun1)
简单自定义函数运算结果
如果自定义函数中涉及到多个参数,此时需要使用args传参,一般第一个函数默认为apply处理数据对象,所以agrs传参从第二个参数开始。如以下代码,判断A列是否大于B列均值,此时将B列以参数传入。
def fun2(x,y):
if x>np.mean(y):
return 1
else:
return 0
data.loc[:,'A'].apply(fun2,args=(data.loc[:,'B'],))
多参数自定义函数示例结果
三、同时运用多个函数
有时候需要批量对同一列数据运用多个函数,这里只需以list将运用的函数传入即可。如下
data.loc[:,'A'].apply([str,float,int])
同时运用多个函数
四、对所有列运用同一函数
如需要同时对data数据集中所有列运用float函数,直接使用data.apply(float)时,会报错,此时使用apply的一个变种函数applymap()即可完美解决。
data.apply(float)# 报类型错误
TypeError: cannot convert the series to <class 'float'>
data.applymap(float)
applymap操作所有数据
其实,还可以使用第三节中的方法对所有数据运用相同算法,如,使用list传入一个函数,对整个data数据集进行处理。
data.apply([float])
apply方法实现所有数据运用相同函数
那么到这里,聪明的小伙伴肯定一下就能想到如何使用多个函数运用到所有或多列数据中,实现代码如下:
data.apply([str,float,int])

多个函数运用到多列数据
五、与lambda联合使用
apply与lambda的联合使用简直就是神级组合,二者配合,在进行多行或多列数据整合或判断时,非常的方便和快捷;
如需要判断data数据集中A列数值是否大于B列的0.5倍,满足条件返回1,否则返回0,并赋值为C列;
代码如下,此时需要控制axis=1,否则找不到A和B列。
data.loc[:,'C'] = data.apply(lambda x: 1 if x['A'] > (x['B']*0.5) else 0,axis=1)
受限于篇幅这里只简单介绍了lambda和apply的使用方法的一种,后续可以专门拿出时间详细的写一下二者配合使用在数据分析中的技巧。
六、与guoupby配合使用实现分组拼接
如需要根据某列进行分组,对目标列数据进行分组拼接,类似于SQL中的group_concat函数的功能;
这里使用了之前的一个案例,对data_q内数据根据BMI_group进行分组,取出不同BMI_group下Estimate的值,操作代码如下:首先使用groupby进行分组之后,然后使用apply函数取出Estimate列并整合为list。
data_q.groupby("BMI_group",sort=False).apply(lambda x:list((x["Estimate"])))
七、总结
apply的使用方法或技巧远不止这些,后面有时间会结合详细的案例针对某一点介绍更多的方法和技巧;同时也欢迎大家有好的想法或思路跟我沟通,共同学习进步。