Python进行项目上的工具开发,在用到Pandas这个包时,发现其groupby功能真的逆天,相比sas而言,代码上真的简化很多,而且我认为从原理上来说,其groupby相当于实现了并行功能,就是各组同时在进行数据处理,顺序不分先后。相比sas的永远row by row处理,在速度上理论上是要快很多的。
对于Pandas的groupby,其能够实现各种描述统计mean、sum或者取first或者head取前几行这些功能,我觉得这个并没有惊艳到我。
让我惊叹的是它的apply功能,可以涵盖对Pandas groupby之后的任何组内处理,尤其是涉及到上下行的关联处理时,也可以直接通过自定义函数来实现。
例如,本次分享下Python是如何通过Pandas的groupby实现组内的多个列累加,也就是在groupby后的每一个组内,每一行的结果都是之前所有行结果的和。
从实现逻辑上来讲,这个并不复杂。首先给一个SAS的处理示范代码:
data want;
set template;
by groupbyvar;
retain sum1-sum2 0;
if first.groupbyvar then d0;sum1=var1;sum2=var2;end;
else do;sum1=sum1+var1;sum2=sum2+var2;end;
run;
SAS处理一般正常就是首先by之后通过first语句赋值var1给sum1赋值var2给sum2,然后通过retain实现var1和var2累加,最后得到新的变量sum1和sum2。
那么让我们们来看看Python基于同样的逻辑是如何实现的。
先给一个简单的数据集example:
import pandas as pd, numpy as np
template=pd.DataFrame({
"groupbyvar":["A","A","A","B","B"],
"var1":np.random.randint(5,50,5),
"var2":np.random.randint(15,50,5)
})
得到一个包含3个变量,5行数据的数据集:
接下来自定义一个函数,通过上述逻辑来实现累加:
def multiplecolumn_sum(x):
new_x=x.reset_index(drop=True)
sum1, sum2=0, 0
for id, row in new_x.iterrows():
sum1, sum2=row['var1']+sum1, row['var2']+sum2
new_x.loc[id,'sum1'], new_x.loc[id,'sum2']=sum1, sum2
return new_x
然后通过apply调用函数:
want=template.groupby('groupbyvar').apply(multiplecolumn_sum)
want=want.reset_index(drop=True)
自此,就可以得到两个新的累加之后的列sum1和sum2:
可以看到对A组和B组分别实现每一行都是基于前面所有行的累加。
总的来讲,Pandas的groupby通过把一个大的dataframe切割成N个小的各自独立的dataframe后,通过apply就可以实现小dataframe内部的内部独立处理而互不影响其他dataframe,这种并行处理的方式才最吸引我。