pandas之分組聚合(agg,apply)


Pandas分組聚合 - 高級


自定義聚合方式

在分組聚合的split-apply-combine過程中,apply是核心。Python 本身有高階函數 apply() 來實現它

自定義聚合方式:aggregate(),或agg()

之前的聚合方式,所有列只能應用一個相同的聚合函數

agg()自定義聚合方式的優勢:

聚合參數是列表
    對數據每列應用多個相同的聚合函數
聚合參數是字典
    對數據的每列應用一個或多個不同的聚合函數
聚合參數是自定義函數
    對數據進行一些復雜的操作
agg 方法將一個函數使用在一個數列上,然后返回一個標量的值。也就是說agg每次傳入的是一列數據,對其聚合后返回標量

自定義聚合方式可以:

每個列應用不同的聚合方式
一個列應用多個聚合方式

 

 

df = pd.DataFrame({
    'name': ['張三','李四','王五','李四','王五','王五','趙六'],
    'chinese': [18, 53, 67, 63, 59, 70, 94],
    'math': [82, 63, 41, 59, 46, 39, 58],
    'english': [68, 52, 80, 86, 60, 98, 64],
    'test': ['一','一','一','二','二','三','一']
})
# 使用自定義聚合方式實現
df.groupby('name').agg(sum)
#聚合參數是列表
df.groupby('name').agg([sum, 'mean', np.min])  # 列表參數函數可以有多種不同寫法:直接寫函數名(容易出錯),函數名寫成字符串,ndarray數組函數
# 將聚合列索引改為自定義方式,元組實現
df.groupby('name')['chinese', 'math'].agg([('求和', sum), ('平均值', 'mean'), ('最小值', min)])
# 語文列聚合函數:求和
df.groupby('name').agg({'chinese': sum})
# 選中的多個列,每列都應用不同的多個聚合函數
df.groupby('name').agg({'chinese': [sum, 'mean'], 'math': [np.min, np.max]})

聚合參數是自定義函數

用於一些較為復雜的聚合工作

  • 自定義聚合函數要比系統自帶的、經過優化的函數慢得多。
  • 因為在構造中間分組數據塊時存在非常大的開銷(函數調用、數據重排等)
def aaa(x):
    return x.max() - x.min()

df.groupby('name').agg(aaa)
# 匿名函數實現
df.groupby('name').agg(lambda x: x.max() - x.min())

#例:返回 DataFrame 某一列中 n 個最大值
# 定一個 top 函數,返回 DataFrame 某一列中 n 個最大值
def top(df, n=2, column='chinese'):
    return df.sort_values(by=column, ascending=False)[:n]
# 自定義函數分組聚合參數
df.groupby('name').apply(top, n=1, column='math')

總結在學習apply函數用法時候,他是可以作用dataframe.series,所以
def bbb(x):
    return x['chinese'].mean() >= 60
df.groupby('name').agg(bbb)  # 報錯
df.groupby('name').apply(bbb)  # 返回seies
def bbb(x):
    return x.mean() >= 60
df.groupby('name').agg(bbb)  # 返回datafrmae布爾值
df.groupby('name').apply(bbb)  # 返回dataframe布爾值

  

過濾數據

例子:輸出所有語文考試平均分及格的數據

def bbb(x):
    return x.mean() >= 60

df.groupby('name').agg(bbb)  # 返回布爾值
df.groupby('name').filter(bbb)
#輸出所有語文平均分及格的學生
df.groupby('name').filter(bbb).groupby('name').mean()

使用 transform 函數對所有的數據元素進行轉換計算

def ccc(x):
    return x + 10

df.groupby('name').transform(ccc)
# 使用向量化運算方式實現
df[['chinese', 'math', 'english']] + 10

禁止分組鍵

分組鍵會跟原始對象的索引共同構成結果對象中的層次化索引

將group_keys=False傳入groupby即可禁止該效果

df.groupby(['name','test']).sum()
df.groupby(['name','test'], as_index=False).sum()
	name	test	chinese	math	english
0	張三	一	18	82	68
1	李四	一	53	63	52
2	李四	二	63	59	86
3	王五	一	67	41	80
4	王五	三	70	39	98
5	王五	二	59	46	60
6	趙六	一	94	58	64

# 刪除,刪除分組帶來的外層索引
df.groupby('name').apply(top, n=2, p='math')
df.groupby('name', as_index=False).apply(top, n=2, p='math')
df.groupby('name', group_keys=False).apply(top, n=2, p='math')

  

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM