使用groupby方法拆分数据
本节内容属于同一个程序,在同一个文件中运行
DateFrame.groupby(by=None,axis=0,level=None,as_index=True,sort=True,group_key=True,squeeze=False,**kwargs)
by=None 进行分组的依据
axis=0,操作的纵向,默认对列操作,默认值为0,与drop默认方向不同,注意区别
level=None
as_index=True 表示聚合后的标签是否以DateFrame索引形式输出
sort=True,group_key=True,默认对数据竞选排序
squeeze=False 表示是否对数组进行降维
import pandas as pd
import numpy as np
date=pd.read_excel('meal_order_detail.xlsx')
date_group=date[['order_id','counts','amounts']].groupby(by='order_id')
#分组后的数据对象类似于series与dateframe,是pandas提供的一种对象
print('date_group的数据类型为:\n',type(date_group))
date_group的数据类型为:
<class 'pandas.core.groupby.generic.DataFrameGroupBy'>
print('分组后前五组的均值为:\n',date_group.mean().head())
分组后前五组的均值为:
counts amounts
order_id
137 1.500000 32.333333
165 1.166667 52.944444
166 1.400000 48.200000
171 1.428571 36.285714
177 1.000000 34.250000
print('分组后前五组每组数据的大小为:\n',date_group.size().head())
分组后前五组每组数据的大小为:
order_id
137 6
165 18
166 5
171 7
177 4
dtype: int64
使用agg方法聚合数据
print('订单详情表中销量和售价的和与均值')
#注意pandas中没有提供sum函数
print(date[['counts','amounts']].agg([np.sum,np.mean]))
订单详情表中销量和售价的和与均值
counts amounts
sum 3088.000000 125992.000000
mean 1.111191 45.337172
#使用agg分别求字段不同的统计量,此时agg输入参数为字典,字典的形式每个字段对应的统计量
print('订单数据中,销售量counts的总和以及售价amounts的均值')
print(date.agg({'counts':np.sum ,'amounts':np.mean}))
订单数据中,销售量counts的总和以及售价amounts的均值
counts 3088.000000
amounts 45.337172
dtype: float64
print('订单数据中,销售量counts的总和以及售价amounts的均值和总和')
print(date.agg({'counts':np.sum ,'amounts':[np.mean,np.sum]}))
订单数据中,销售量counts的总和以及售价amounts的均值和总和
counts amounts
mean NaN 45.337172
sum 3088.0 125992.000000
#agg还可以传入自定义的函数
def fun(n):
k=n.sum()-50
return k
print('使用自定义函数,销量整体都减少50')
print(date.agg({'counts':fun},axis=0))
使用自定义函数,销量每个都减少50
counts 3038
dtype: int64
注意count与value_counts的区别
print(date['counts'].count())
print(len(date['counts']))
print(date['counts'].value_counts())
2779
2779
1 2638
2 79
3 19
4 19
6 12
8 6
5 3
7 2
10 1
Name: counts, dtype: int64
date_group=date[['order_id','counts','amounts']].groupby(by='order_id')
date_group_mean=date_group.agg(np.mean).head()
print('分组后前五组数据的均值为:\n',date_group_mean)
分组后前五组数据的均值为:
counts amounts
order_id
137 1.500000 32.333333
165 1.166667 52.944444
166 1.400000 48.200000
171 1.428571 36.285714
177 1.000000 34.250000
#使用agg方法对分组数据中不同的属性,使用不同的聚合函数
date_group_agg=date_group.agg({'counts':np.mean,'amounts':[np.mean,np.sum]}).head()
print('分组后前五组数据销售量的均值以及售价的均值和总和')
print(date_group_agg)
分组后前五组数据销售量的均值以及售价的均值和总和
counts amounts
mean mean sum
order_id
137 1.500000 32.333333 194
165 1.166667 52.944444 953
166 1.400000 48.200000 241
171 1.428571 36.285714 254
177 1.000000 34.250000 137
使用apply函数
apply函数类似于agg方法,能够将函数应用于每一列
与apply相比,agg函数对于不同的字段能够使用不同的函数获取不同的结果,apply对不同的字段只能应用同样的函数
print('分组后前五组,每组的三个字段的均值为:')
print(date_group.apply(np.mean).head())
分组后前五组,每组的三个字段的均值为:
order_id counts amounts
order_id
137 137.0 1.500000 32.333333
165 165.0 1.166667 52.944444
166 166.0 1.400000 48.200000
171 171.0 1.428571 36.285714
177 177.0 1.000000 34.250000
使用transform聚合函数
#使用transform方法聚合函数对这个DateFrame的所有元素进行操作
print('原始数据:\n',date[['counts','amounts']].head())
print('使用transform将销量和售价翻倍\n',date[['counts','amounts']].transform(lambda x:x*2).head())
原始数据:
counts amounts
0 1 49
1 1 48
2 1 30
3 1 25
4 1 13
使用transform将销量和售价翻倍
counts amounts
0 2 98
1 2 96
2 2 60
3 2 50
4 2 26
#使用transform对分组后的date_group对象进行操作
print('使用transform对分组后的date_group对象求均值\n',date_group.transform(lambda x :x.mean()).head())
使用transform对分组后的date_group对象求均值
counts amounts
0 1.0 33.0
1 1.0 33.0
2 1.0 33.0
3 1.0 33.0
4 1.0 33.0
下面内容续写的
利用pivot_table可以实现透视表
import pandas as pd
import numpy as np
date=pd.read_excel('meal_order_detail.xlsx')
datepivot=pd.pivot_table(date[['order_id','counts','amounts']],index = 'order_id')
print('以order_id作为分组键创建的透视表为:\n',datepivot.head())
以order_id作为分组键创建的透视表为:
amounts counts
order_id
137 32.333333 1.500000
165 52.944444 1.166667
166 48.200000 1.400000
171 36.285714 1.428571
177 34.250000 1.000000
使用pivot_table时,如果没有指定aggfunc,默认使用np.mean来进行计算,np.mean会过滤非数值类型
和groupby方法分组相同,该方法在创建透视表的时候分组键可以有多个
datepivot2=pd.pivot_table(date[['order_id','dishes_name','counts','amounts']],
index = ['order_id','dishes_name'],
aggfunc=np.sum)
print('含有两个index的透视表为:\n',datepivot2.head(7))
含有两个index的透视表为:
amounts counts
order_id dishes_name
137 农夫山泉NFC果汁100%橙汁 6 1
凉拌菠菜 27 1
番茄炖牛腩\r\n 35 1
白饭/小碗 1 4
西瓜胡萝卜沙拉 26 1
麻辣小龙虾 99 1
165 38度剑南春 80 1
datepivot3=pd.pivot_table(date[['order_id','dishes_name','counts','amounts']],
index = 'order_id',
columns = 'dishes_name',
aggfunc=np.sum)
print('以order_id作为行分组键,dishes_name作为列分组键的透视表为:\n',datepivot3.iloc[:6,:6])
以order_id作为行分组键,dishes_name作为列分组键的透视表为:
amounts
dishes_name 42度海之蓝 北冰洋汽水 38度剑南春 50度古井贡酒 52度泸州老窖 53度茅台
order_id
137 NaN NaN NaN NaN NaN NaN
165 NaN NaN 80.0 NaN NaN NaN
166 NaN NaN NaN NaN NaN NaN
171 NaN NaN NaN NaN NaN NaN
177 NaN NaN NaN NaN NaN NaN
193 NaN NaN NaN NaN NaN NaN
Nan表示数据为空,如果需要用值填充,可在输入参数最后声明 fll_value=0
交叉表crosstab,该函数的用法和pivot_table一样,不同的是输入的参数,
crosstable中的参数index,cloumns,values需要从DateFrame中取出一列
datecrosstab=pd.crosstab(index = date['order_id'],
columns = date['dishes_name'],
values=date['counts'],
aggfunc=np.sum)
print('以order_id作为行分组键,dishes_name作为列分组键的交叉为:\n',datecrosstab.iloc[:6,:6])
以order_id作为行分组键,dishes_name作为列分组键的交叉为:
dishes_name 42度海之蓝 北冰洋汽水 38度剑南春 50度古井贡酒 52度泸州老窖 53度茅台
order_id
137 NaN NaN NaN NaN NaN NaN
165 NaN NaN 1.0 NaN NaN NaN
166 NaN NaN NaN NaN NaN NaN
171 NaN NaN NaN NaN NaN NaN
177 NaN NaN NaN NaN NaN NaN
193 NaN NaN NaN NaN NaN NaN