5. 数据聚合【重点】
数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。
数据分类处理:
- 分组:先把数据分为几组
- 用函数处理:为不同组的数据应用不同的函数以转换数据
- 合并:把不同组得到的结果合并起来
数据分类处理的核心: groupby()函数
- 创建数据集
df = DataFrame({'item':np.random.randint(0,4,50),
'level':np.random.randint(0,3,size = 50),
'price':np.random.randint(1,10,size = 50),
'sailer':np.random.randint(0,3,size = 50),
'weight':np.random.randint(50,100,size = 50)})
df
- 赋值转换
# = 赋值 :使用map({字典集})
df['item'] = df['item'].map({0:'萝卜',1:'白菜',2:'西红柿',3:'黄瓜'})
df['level'] = df['level'].map({0:'差',1:'中',2:'优'})
df['sailer'] = df['sailer'].map({0:'张大妈',1:'李大妈',2:'赵大叔'})
df
- 聚合操作
# 按 sailer,item分组,显示价格的最大值
aa=df.groupby(['sailer','item'])['price'].max()
aa
Out:[Series]
sailer item
张大妈 白菜 8
萝卜 8
西红柿 9
黄瓜 2
李大妈 白菜 4
萝卜 6
西红柿 7
黄瓜 9
赵大叔 白菜 8
萝卜 9
西红柿 8
黄瓜 8
Name: price, dtype: int32
# 按等级,类别分组,显示价格和体重的最小值
df.groupby(['level','item'])['price','weight'].min()
- 求总和
weight_sum = df.groupby(['level'])['weight'].sum()
weight_sum
Out:
level
中 1570
优 790
差 1250
Name: weight, dtype: int64
weight_sum = DataFrame(weight_sum)
weight_sum
# 给表头修改名字
weight_sum = weight_sum.rename({'weight':'weight_sum'},axis = 1)
weight_sum
- 合并聚合表格【左连接:left_on='level',right_index=True】注意:没有right_index=True会报错
df2 = df.merge(weight_sum,left_on='level',right_index=True)
df2
- 求平均价格
price_mean = df.groupby(['item'])['price'].mean()
price_mean = DataFrame(price_mean)
price_mean
# 修改标题名称
price_mean.columns = ['price_mean']
price_mean
- 合并聚合数据表格
df2.merge(price_mean,left_on='item',right_index=True)
============================================
练习23:
- 假设菜市场张大妈在卖菜,有以下属性:
- 菜品(item):萝卜,白菜,辣椒,冬瓜
- 颜色(color):白,青,红
- 重量(weight)
- 价格(price)
- 要求以属性作为列索引,新建一个ddd
- 对ddd进行聚合操作,求出颜色为白色的价格总和
- 对ddd进行聚合操作,求出萝卜的所有重量(包括白萝卜,胡萝卜,青萝卜)以及平均价格
- 使用merge合并总重量及平均价格
============================================
# 测试choice
np.random.choice([0,1,2],size=10)
Out:
array([1, 0, 1, 1, 0, 2, 2, 1, 2, 2])
- 创建数据集
ddd=DataFrame({'item':np.random.choice(['萝卜','白菜','辣椒','冬瓜'],size=50),
'color':np.random.choice(['白','青','红'],size=50),
'weight':np.random.randint(10,100,50),
'price':np.random.randint(1,10,50)
})
ddd
- 求出颜色为白色的价格总和
ddd.color.map(lambda x:x=='白').sum()
Out: 19
- 对ddd进行聚合操作,求出萝卜的所有重量(包括白萝卜,胡萝卜,青萝卜)以及平均价格
p=ddd.groupby('item')['price'].mean()
p=DataFrame(p)
p
p.index
Out: Index(['冬瓜', '白菜', '萝卜', '辣椒'], dtype='object', name='item')
p.columns
Out: Index(['price'], dtype='object')
w=ddd.groupby('item')['weight'].sum()
w=DataFrame(w)
w
- 使用merge合并总重量及平均价格
p.merge(w,left_index=True,right_index=True)
p.join(w)
============================================
6.0 高级数据聚合
可以使用pd.merge()函数将聚合操作的计算结果添加到df的每一行
使用groupby分组后调用加和等函数进行运算,让后最后可以调用add_prefix(),来修改列名
可以使用transform和apply实现相同功能
在transform或者apply中传入函数即可
- 采用上面的数据集
- 使用apply
df.groupby(['sailer','item'])['price'].apply(np.mean)
- 使用transform
# apply和transform都可以进行分组计算,计算结果一样
# 表现形式不同,apply多层索引,图形直观,简洁
# transform 一层索引,所有的数据,级联方便
mean_price = df.groupby(['sailer','item'])[['price']].transform(np.mean).add_prefix('mean_')
mean_price
- 使用pd.concat()拼接mean_price
pd.concat([df,mean_price],axis = 1)
transform()与apply()函数还能传入一个函数或者lambda
df = DataFrame({'color':['white','black','white','white','black','black'],
'status':['up','up','down','down','down','up'],
'value1':[12.33,14.55,22.34,27.84,23.40,18.33],
'value2':[11.23,31.80,29.99,31.18,18.25,22.44]})
举栗子
dic = {
'item':['萝卜','白菜','萝卜','辣椒','冬瓜','冬瓜','萝卜','白菜'],
'color':['red','white','green','red','green','white','white','green'],
'weight':[12,30,16,5,10,5,25,18],
'price':[2.5,0.8,3.5,4,1.2,1.5,0.9,3]
}
df = DataFrame(data=dic)
df
定义函数
# 定义求和
def m_sum(items):
sum=0
for item in items:
sum+=item
return sum
# 定义求平均
def my_mean(items): #参数为复数(List形式)
sum=0
for item in items:
sum+=item
return sum/items.size
df.groupby(by='item')['weight'].apply(m_sum)['萝卜']
Out:
53
df.groupby(by='item')['price'].apply(my_mean)
Out:
item
Apple 3.00
Banana 2.75
Orange 3.50
Name: price, dtype: float64