程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Pandas知識點-詳解聚合函數agg

編輯:Python

Pandas知識點-詳解聚合函數agg

Pandas提供了多個聚合函數,聚合函數可以快速、簡潔地將多個函數的執行結果聚合到一起。
本文介紹的聚合函數為DataFrame.aggregate(),別名DataFrame.agg(),aggregate()和agg()是同一個函數,僅名字不同。
agg()參數和用法介紹
agg(self, func=None, axis=0, *args, **kwargs):

  • func: 用於聚合數據的函數,如max()、mean()、count()等,函數必須滿足傳入一個DataFrame能正常使用,或傳遞到DataFrame.apply()中能正常使用。
    func參數可以接收函數的名字、函數名的字符串、函數組成的列表、行/列標簽和函數組成的字典。
  • axis: 設置按列還是按行聚合。設置為0或index,表示對每列應用聚合函數,設置為1或columns,表示對每行應用聚合函數。
  • *args: 傳遞給函數func的位置參數。
  • **kwargs: 傳遞給函數func的關鍵字參數。

返回的數據分為三種:scalar(標量)、Series或DataFrame。

  • scalar: 當Series.agg()聚合單個函數時返回標量。
  • Series: 當DataFrame.agg()聚合單個函數時,或Series.agg()聚合多個函數時返回Series。
  • DataFrame: 當DataFrame.agg()聚合多個函數時返回DataFrame。

傳入單個參數

# coding=utf-8
import pandas as pd
import numpy as np
df = pd.DataFrame(
{
'Col-1': [1, 3, 5], 'Col-2': [2, 4, 6],
'Col-3': [9, 8, 7], 'Col-4': [3, 6, 9]},
index=['A', 'B', 'C'])
print(df)
 Col-1 Col-2 Col-3 Col-4
A 1 2 9 3
B 3 4 8 6
C 5 6 7 9
res1 = df.agg(np.mean)
print('-' * 30, '\n', res1, sep='')
res2 = df.mean() # 調用Python內置函數
print('-' * 30, '\n', res2, sep='')
res3 = df['Col-1'].agg(np.mean)
print('-' * 30, '\n', res3, sep='')
------------------------------
Col-1 3.0
Col-2 4.0
Col-3 8.0
Col-4 6.0
dtype: float64
------------------------------
Col-1 3.0
Col-2 4.0
Col-3 8.0
Col-4 6.0
dtype: float64
------------------------------
3.0

DataFrame應用單個函數時,agg()的結果與用apply()的結果等效,用DataFrame調用Python的內置函數也可以實現相同效果。
apply()詳解參考:Pandas知識點-詳解行列級批處理函數apply
Series對象在agg()中傳入單個函數,聚合結果為標量值,也就是單個數據。
多種方式傳入函數func

# 用列表的方式傳入
res4 = df.agg([np.mean, np.max, np.sum])
print('-' * 30, '\n', res4, sep='')
# 用字典的方式傳入
res5 = df.agg({
'Col-1': [sum, max], 'Col-2': [sum, min], 'Col-3': [max, min]})
print('-' * 30, '\n', res5, sep='')
# 函數名用字符串的方式傳入
res6 = df.agg({
'Col-1': ['sum', 'max'], 'Col-2': ['sum', 'min'], 'Col-3': ['max', 'min']})
print('-' * 30, '\n', res6, sep='')
------------------------------
Col-1 Col-2 Col-3 Col-4
mean 3.0 4.0 8.0 6.0
amax 5.0 6.0 9.0 9.0
sum 9.0 12.0 24.0 18.0
------------------------------
Col-1 Col-2 Col-3
sum 9.0 12.0 NaN
max 5.0 NaN 9.0
min NaN 2.0 7.0
------------------------------
Col-1 Col-2 Col-3
sum 9.0 12.0 NaN
max 5.0 NaN 9.0
min NaN 2.0 7.0

在agg()中,可以用列表的方式傳入多個函數,會將這些函數在每一列的執行結果聚合到一個DataFrame中,結果DataFrame中的索引為對應的函數名。
也可以用字典的方式按列/行指定聚合函數,會將指定列/行與對應函數的執行結果聚合到一個DataFrame中,列/行和函數沒有對應關系的位置填充空值。
在上面的情況中,函數名都可以換成用字符串的方式傳入,結果一樣。

# 用元組的方式按列/行傳入函數
res7 = df.agg(X=('Col-1', 'sum'), Y=('Col-2', 'max'), Z=('Col-3', 'min'),)
print('-' * 30, '\n', res7, sep='')
res8 = df.agg(X=('Col-1', 'sum'), Y=('Col-2', 'max'), Zmin=('Col-3', 'min'), Zmax=('Col-3', 'max'))
print('-' * 30, '\n', res8, sep='')
------------------------------
Col-1 Col-2 Col-3
X 9.0 NaN NaN
Y NaN 6.0 NaN
Z NaN NaN 7.0
------------------------------
Col-1 Col-2 Col-3
X 9.0 NaN NaN
Y NaN 6.0 NaN
Zmin NaN NaN 7.0
Zmax NaN NaN 9.0

agg()還支持將不同的列/行和函數組合成元組,賦值給一個自定義的索引名,聚合結果DataFrame的索引按自定義的值重命名。
用這種方式傳入函數時,元組中只能有兩個元素:列/行名和一個函數,不能同時傳入多個函數,如果要對同一列/行執行多個函數,需要用多個元組多次賦值。
傳入自定義函數和匿名函數

def fake_mean(s):
return (s.max()+s.min())/2
res9 = df.agg([fake_mean, lambda x: x.mean()])
print('-' * 40, '\n', res9, sep='')
res10 = df.agg([fake_mean, lambda x: x.max(), lambda x: x.min()])
print('-' * 40, '\n', res10, sep='')
----------------------------------------
Col-1 Col-2 Col-3 Col-4
fake_mean 3.0 4.0 8.0 6.0
<lambda> 3.0 4.0 8.0 6.0
----------------------------------------
Col-1 Col-2 Col-3 Col-4
fake_mean 3.0 4.0 8.0 6.0
<lambda> 5.0 6.0 9.0 9.0
<lambda> 1.0 2.0 7.0 3.0

傳入自定義函數和匿名函數時,聚合結果中對應的索引也是顯示函數名字,匿名函數顯示<lambda>,有多個匿名函數時,同時顯示<lambda>。
這裡需要注意,只有匿名函數可以傳入重復的函數,自定義函數和內置函數等不能重復,會報錯SpecificationError: Function names must be unique if there is no new column names assigned。
自定義實現describe函數的效果

print(df.describe())
 Col-1 Col-2 Col-3 Col-4
count 3.0 3.0 3.0 3.0
mean 3.0 4.0 8.0 6.0
std 2.0 2.0 1.0 3.0
min 1.0 2.0 7.0 3.0
25% 2.0 3.0 7.5 4.5
50% 3.0 4.0 8.0 6.0
75% 4.0 5.0 8.5 7.5
max 5.0 6.0 9.0 9.0

describe()函數包含了數值個數、均值、標准差、最小值、1/4分位數、中位數、3/4分位數、最大值。

from functools import partial
# 20%分為數
per_20 = partial(pd.Series.quantile, q=0.2)
per_20.__name__ = '20%'
# 80%分為數
per_80 = partial(pd.Series.quantile, q=0.8)
per_80.__name__ = '80%'
res11 = df.agg([np.min, per_20, np.median, per_80, np.max])
print('-' * 40, '\n', res11, sep='')
 Col-1 Col-2 Col-3 Col-4
amin 1.0 2.0 7.0 3.0
20% 1.8 2.8 7.4 4.2
median 3.0 4.0 8.0 6.0
80% 4.2 5.2 8.6 7.8
amax 5.0 6.0 9.0 9.0

用agg()函數可以聚合實現describe()相同的效果,只要將函數組合在一起傳給agg()即可。所以我們可以根據自己的需要來增加或裁剪describe()中的內容。
上面的例子中,pd.Series.quantile()是pandas中求分位數的函數,默認是求中位數,指定q參數可以計算不同的分位數。
partial()是Python的functools內置庫中的函數,作用是給傳入它的函數固定參數值,如上面分別固定quantile()的q參數為0.2/0.8。
分組聚合結合使用

# 先用groupby()分組再用agg()聚合
res12 = df.groupby('Col-1').agg([np.min, np.max])
print('-' * 40, '\n', res12, sep='')
# 分組後只聚合某一列
res13 = df.groupby('Col-1').agg({
'Col-2': [np.min, np.mean, np.max]})
print('-' * 40, '\n', res13, sep='')
----------------------------------------
Col-2 Col-3 Col-4
amin amax amin amax amin amax
Col-1
1 2 2 9 9 3 3
3 4 4 8 8 6 6
5 6 6 7 7 9 9
----------------------------------------
Col-2
amin mean amax
Col-1
1 2 2.0 2
3 4 4.0 4
5 6 6.0 6

agg()經常接在分組函數groupby()的後面使用,先分組再聚合,分組之後可以對所有組聚合,也可以只聚合需要聚合的組。
groupby()詳解參考:Pandas知識點-詳解分組函數groupby

res14 = df.groupby('Col-1').agg(
c2_min=pd.NamedAgg(column='Col-2', aggfunc='min'),
c3_min=pd.NamedAgg(column='Col-3', aggfunc='min'),
c2_sum=pd.NamedAgg(column='Col-2', aggfunc='sum'),
c3_sum=pd.NamedAgg(column='Col-3', aggfunc='sum'),
c4_sum=pd.NamedAgg(column='Col-4', aggfunc='sum')
)
print('-' * 40, '\n', res14, sep='')
----------------------------------------
c2_min c3_min c2_sum c3_sum c4_sum
Col-1
1 2 9 2 9 3
3 4 8 4 8 6
5 6 7 6 7 9

pd.NamedAgg可以對聚合進行更精准的定義,它包含column和aggfunc兩個定制化的字段,column設置用於聚合的列,aggfunc設置用於聚合的函數。
借助pd.NamedAgg,可以給column和aggfunc的組合自定義命名,自定義命名體現為聚合結果中的列名。
以上就是pandas中聚合函數agg()的用法介紹和分析,如果本文的內容對你有幫助,歡迎點贊、評論、收藏,也可以關注和聯系我一起交流討論。

參考文檔:
[1] pandas中文網:https://www.pypandas.cn/docs/


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved