Pandas groupby apply agg 的區別 運行自定義函數說明
agg 方法將一個函數使用在一個數列上,然後返回一個標量的值。也就是說agg每次傳入的是一列數據,對其聚合後返回標量。
對一列使用三個函數:
對不同列使用不同函數
apply 是一個更一般化的方法:將一個數據分拆-應用-匯總。而apply會將當前分組後的數據一起傳入,可以返回多維數據。
實例:
1、數據如下:
lawsuit2[['EID','LAWAMOUNT','LAWDATE']]
2、groupby後應用apply傳入函數數據如下:
lawsuit2[['EID','LAWAMOUNT','LAWDATE']].groupby(['EID']).apply(lambda df:print(df))
3、如果使用agg,對於兩列可以處理,但對於上面的三列,打印數據如下:
lawsuit2[['EID','LAWAMOUNT','LAWDATE']].groupby(['EID']).agg(lambda df:print(df))
可以看到agg傳入的隻有一列數據,如果我們使用df加列下表強行取值也能取到,但是有時會出現各種keyError問題。
4、完整代碼:
判斷最近一次日期的花費是否是所有的花費中最大花費。
def handle(df): # print(df) # 找最大日期 maxdate = df['LAWDATE'].max() # 找最大費用 left = df[ df['LAWDATE']==maxdate ]['LAWAMOUNT'].max() # 取ID EID = df['EID'].values[0] # print(EID) # 從已存在的表中根據EID找到最大費用 right = LAW_AMOUNT_MAX.loc[EID,'LAW_AMOUNT_MAX'] # 判斷費用是否相等 if left==right: return 1 else: return 0 LAW_AMOUNT_MAX_IS_LAST = lawsuit2[['EID','LAWAMOUNT','LAWDATE']].groupby(['EID']).apply(handle)
其他註意點:
在groupby後使用apply,如果直接返回,會出現有多餘的groupby索引問題,可以使用group_keys解決:
orgin = reviews_df.sort_values(["reviewerID","unixReviewTime"]).groupby("reviewerID",group_keys=False) train = orgin.apply(lambda df: df[:-2]) train.head()
補充:pandas分組聚合運算groupby之agg,apply,transform
groupby函數是pandas中用以分組的函數,可以通過指定列來進行分組,並返回一個GroupBy對象。對於GroupBy對象的聚合運算,其有經過優化的較為常用的sum,mean等函數,但是如果我們需要用自定義的函數進行聚合運算,那麼就需要通過agg,apply,transform來實現。
agg,apply和transform三者之間的區別在於:1、agg和transform之間的區別為:前者經過聚合後,隻會在該組單列中返回一個標量值,而transform則會將該標量值在該組單列內進行廣播,保持原DataFrame的索引不變;2、agg和transform中的函數參數是以分組後的單列(Series)為操作對象的,即傳入agg和transform的函數的參數是列,而apply中的函數參數是分組後整個的DataFrame。下面分別對這兩點進行說明。
一、agg和transform
如下代碼所示,構造一個df,agg和transform中lambda函數的input都為單列,但是agg返回的索引是分組的key的唯一值,而transform返回的索引和原df一樣,但是相比於agg返回的結果,發現transform隻是在d行處的值進行瞭重復的廣播,這個目的就是維持原df的索引不變,且被拿來分組的列會被剔除。
df Out[1]: index a b c 0 d 0 1 2 1 d 3 4 5 2 e 6 7 8 df.groupby(by='index').agg(lambda x:x.shape) Out[2]: a b c index d (2,) (2,) (2,) e (1,) (1,) (1,) df.groupby(by='index').transform(lambda x:x.shape) Out[3]: a b c 0 (2,) (2,) (2,) 1 (2,) (2,) (2,) 2 (1,) (1,) (1,)
二、agg和apply
下面的是apply的結果,相比於上面agg的結果,可以發現,實際上lambda函數的input不再是一個Series,而是分組後的整個DataFrame。
dd.groupby(by='index').apply(lambda x:x.shape) Out[4]: index d (2, 4) e (1, 4)
三、其他註意點
對於agg函數,其不僅可以傳入一個函數對每列執行相同的操作,還可以傳入一個字典{‘col_name’:func},來對不同的列做不同的操作,也可以將func替換為由多個不同的函數組成的list,實現對同一列做多個不同的操作,這是agg函數最為靈活的地方。
這三個函數,參數形式都為(func, *args,**kwargs),所以可以通過位置參數和關鍵字參數給func傳遞額外的參數。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。如有錯誤或未考慮完全的地方,望不吝賜教。
推薦閱讀:
- Pandas高級教程之Pandas中的GroupBy操作
- pandas中groupby操作實現
- pandas數據分組groupby()和統計函數agg()的使用
- Python groupby函數圖文詳解
- pandas groupby分組對象的組內排序解決方案