總結:
對agg而言,會計算得到A,B,C公司對應的均值並直接返回,但對transform而言,則會對每一條數據求得相應的結果,同一組內的樣本會有相同的值,組內求完均值後會按照原索引的順序返回結果;
import pandas as pd
import numpy as np
'''np.random.randint(x,y,z): 返回從低(含)到高(不含)的隨機整數'''
company=["A","B","C"]
data=pd.DataFrame({
"company":[company[x] for x in np.random.randint(0,len(company),10)],
"salary":np.random.randint(5,50,10),
"age":np.random.randint(15,50,10)
})
data
#### groupby的基本原理
'''DataFrameGroupBy對象'''
group = data.groupby("company")
group
list(group)
for x,y in group:
print(y)
# 總結來說:
# groupby的過程就是將原有的DataFrame按照groupby的字段(這裡是company),劃分為若干個分組DataFrame,被分為多少個組就有多少個分組DataFrame。所以說,**在groupby之後的一系列操作(如agg、apply等),均是基於子DataFrame的操作**。理解了這點,也就基本摸清了Pandas中groupby操作的主要原理;
#### agg 聚合操作
- pandas_round函數參考:https://www.pythonf.cn/read/126948
'''Case1:針對樣例數據集,求不同公司員工的平均年齡和平均薪水,可以按照下方的代碼進行: data.groupby("company").agg('max').apply(lambda x: round(x)) 感覺python中的函數,並非是四捨五入; '''
data.groupby("company").agg('mean').round({
'age': 1,'salary':2})
'''針對不同的列求不同的值:計算不同公司員工的平均年齡以及薪水的中位數'''
data.groupby('company').agg({
'salary':'median','age':'mean'}).round(1)
#### transform
#在上面的agg中,我們學會了如何求不同公司員工的平均薪水,如果現在需要在原數據集中新增一列avg_salary,代表員工所在的公司的平均薪水(相同公司的員工具有一樣的平均薪水),該怎麼實現呢?
avg_salary_dict = data.groupby('company')['salary'].mean().to_dict()
avg_salary_dict
'''map(avg_salary_dict) ——> 實現映射'''
data['avg_salary'] = data['company'].map(avg_salary_dict)
# 方法1:
data['avg_salary'] = data['company'].map(avg_salary_dict)
data.round(2)
# 方法2:
data['avg_salary_transform'] = data.groupby('company')['salary'].transform('mean')
data
data.groupby('company')['salary'].transform('mean')
#總結:
#對agg而言,會計算得到A,B,C公司對應的均值並直接返回,但對transform而言,則會對每一條數據求得相應的結果,同一組內的樣本會有相同的值,組內求完均值後會按照原索引的順序返回結果;
#### apply
# groupby後的apply,以分組後的子DataFrame作為參數傳入指定函數的,基本操作單位是**DataFrame**,而之前介紹的apply的基本操作單位是Series;
'''假設我現在需要獲取各個公司年齡最大的員工的數據:'''
def get_oldest_staff(x):
df = x.sort_values(by = 'age',ascending = True)
return df.iloc[-1,:]
'''as_index的作用是控制聚合輸出是否以組標簽為索引值'''
oldest_staff = data.groupby('company',as_index = False).apply(get_oldest_staff)
oldest_staff
data.groupby('company',as_index = False).max()