一、透视表
二、交叉表
任务实现
数据透视表是数据分析中常见的工具之一,根据一个或多个键值对数据进行聚合,根据行或列的分组将数据划分到各个区域中。说到分组,除了之前所用到的groupby函数,直接使用透视表提供的pivot_table 方法更加方便。
pandas.pivot_table(data,values=None,index=None,columns=None,aggfunc='mean',fill_value=None,margins=False,dropna=True,margins_name
='All')
1.使用订单号作为透视表分组键(索引)制作透视表
import pandas as pd
import numpy as np
from sqlalchemy import create_engine
# 创建数据库连接
engine = create_engine('mysql+pymysql://root:[email protected]:3306/testdb?charset=utf8')
# 读取.sql文件
detail = pd.read_sql_table('meal_order_detail1',con = engine)
# 创建透视表,以order_id作为分组键
detailPivot = pd.pivot_table(detail[['order_id','counts','amounts']],index='order_id')
print('以order_id为分组键的订单透视表为:\n',detailPivot.head())
#以order_id为分组键的订单透视表为:
amounts counts
order_id
1002 32.000 1.0000
1003 30.125 1.2500
1004 43.875 1.0625
1008 63.000 1.0000
1011 57.700 1.0000
import pandas as pd
import numpy as np
from sqlalchemy import create_engine
engine = create_engine('mysql+pymysql://root:[email protected]:3306/testdb?charset=utf8')
detail = pd.read_sql_table('meal_order_detail1',con=engine)
detailgroup = detail[['order_id','counts','amounts']].groupby(by='order_id')
print('订单详情表分组后前5组的均值为:\n',detailgroup.mean().head())
#订单详情表分组后前5组的均值为:
counts amounts
order_id
1002 1.0000 32.000
1003 1.2500 30.125
1004 1.0625 43.875
1008 1.0000 63.000
1011 1.0000 57.700
与使用groupby方法相比pivot_table方法要相对简洁,显然groupby要先创建一个对象,然后在该对象的基础上进行后续操作(聚合);而pivot_table是直接在已有的数据基础上直接操作生成透视表。
2.修改聚合函数
pivot_tale方法中的aggfunc参数的默认是mean(平均数),当我们需要其他聚合方式时,直接传入新的聚合参数即可。
detailPivot1 = pd.pivot_table(detail[['order_id','counts','amounts']],index='order_id',aggfunc = np.sum)
print('以order_id为分组键的订单透视表为:\n',detailPivot1.head())
#以order_id为分组键的订单透视表为:
amounts counts
order_id
1002 224.0 7.0
1003 241.0 10.0
1004 702.0 17.0
1008 315.0 5.0
1011 577.0 10.0
3.使用多列作为索引(行分组)创建透视表
在创建透视表的时候我们可以根据要求对数据表采取多索引设置,仅需要在index参数后传入设置的列表。
detailPivot2 = pd.pivot_table(detail[['order_id','dishes_name','counts','amounts']],index=['order_id','dishes_name'],aggfunc=np.sum)
print('以order_id和dishes_name为分组键创建的订单销售量与销售价总额和透视表为:\n',detailPivot2.head())
#以order_id和dishes_name为分组键创建的订单销售量与销售价总额和透视表为:
amounts counts
order_id dishes_name
1002 凉拌菠菜 27.0 1.0
南瓜枸杞小饼干 19.0 1.0
焖猪手 58.0 1.0
独家薄荷鲜虾牛肉卷 45.0 1.0
白胡椒胡萝卜羊肉汤 35.0 1.0
4.设置columns参数指定列分组
将菜品名称设置为列分组键后,会出现‘双重列索引’,一个是菜品名称,还有一个是counts、amounts作为不同的数据列区展示。
detailPivot3 = pd.pivot_table(detail[['order_id','dishes_name','counts','amounts']],index='order_id',columns='dishes_name',
aggfunc=np.sum)
print('以order_id和dishes_name为行列分组键创建的订单销售量与销售价总额和透视表为:\n',detailPivot3.head(20))
detailPivot3.to_csv('data/detailPivot3.csv',sep=',',index=index=True)
当数据全部列数很多的时候,做只需要你当前需要用到的数据,可以通过指定values参数来实现,例如:上面设置菜品名称为列分组的时候,既有counts、又有amounts,此时我只需要counts的数据,可以将values设为counts。再次预览文件时会发现当前数据里只包含counts的所有数据。
detailPivot7 = pd.pivot_table(detail[['order_id','dishes_name','counts','amounts']],index='order_id',columns='dishes_name',values='counts',
aggfunc=np.sum)
print('以order_id和dishes_name为行列分组键创建的订单销售量与销售价总额和透视表为:\n',detailPivot7.head(20))
detailPivot7.to_csv('data/detailPivot7.csv',sep=',',index=True)
一般情况下难免会有写数据的缺失,这时我们可以使用fill_value参数来指定数值,对缺失的数据进行填充,一般为NAN的用0进行填充。
detailPivot5 = pd.pivot_table(detail[['order_id','dishes_name','counts','amounts']],index='order_id',columns='dishes_name',
aggfunc=np.sum,fill_value=0)
print('以order_id和dishes_name为行列分组键创建的订单销售量与销售价总额和透视表为:\n',detailPivot5.head(5))
detailPivot5.to_csv('data/detailPivot5.csv',sep=',',index=True)
可以更改参数margins参数在透视表分类末尾查看汇总的数据。
detailPivot6 = pd.pivot_table(detail[['order_id','dishes_name','counts','amounts']],index='order_id',columns='dishes_name',
aggfunc=np.sum,fill_value=0,margins=True)
print('添加margins后透视表的前5行4列为:\n',detailPivot6.iloc[:5])
detailPivot6.to_csv('data/detailPivot6.csv',sep=',',index=True)
交叉表是一种特殊的透视表,主要用于计算分组频率。利用pandas提供的crosstab函数可以制作交叉表。
pandas.crosstab(values=None,index,columns,rownames=None,colnames=None,aggfunc=None,margins=False,dropna=True,normlize=False)
交叉表是透视表的一种,crosstab函数的参数和pivot_table的函数基本相同。不同之处在于crosstab函数中的index、columns、values,输入的都是从DataFrame中提取的某一列。
# 使用crosstab创建交叉表
detailCross = pd.crosstab(index=detail['order_id'],columns=detail['dishes_name'],values=detail['counts'],aggfunc=np.sum)
print('以order_id和dishes_name为分组键,counts为值的透视表前5行为:\n',detailCross.iloc[:5,:5])
#以order_id和dishes_name为分组键,counts为值的透视表前5行为:
dishes_name 42度海之蓝 北冰洋汽水 38度剑南春 50度古井贡酒 52度泸州老窖
order_id
1002 NaN NaN NaN NaN NaN
1003 NaN NaN NaN NaN NaN
1004 NaN NaN NaN NaN NaN
1008 NaN NaN NaN NaN NaN
1011 1.0 NaN NaN NaN NaN
我们可以看出,在统计某一分类的频数方面,使用crosstab会比pivot_table更加方便~
返回顶部
pandas透视表(pivot_table)和交叉表(crosstab)使用介绍
Pandas透视表和交叉表
import pandas as pd
import numpy as np
from sqlalchemy import create_engine
# 创建数据库连接
engine = create_engine('mysql+pymysql://root:[email protected]:3306/testdb?charset=utf8')
# 苏区数据库文件
detail = pd.read_sql_table('meal_order_detail1',con = engine)
# 转换时间数据类型
detail['place_order_time'] = pd.to_datetime(detail['place_order_time'])
# 提取日期并新增日期列
detail['date'] = [i.date() for i in detail['place_order_time']]
PivotDetail = pd.pivot_table(detail[['date','dishes_name','counts','amounts']],index='date',aggfunc=np.sum,margins=True)
# 保存为.csv文件
PivotDetail.to_csv('data/PivotDetail.csv',sep=',',index=True)
print('订单详情表单日菜品成交总额与总数透视表前5行为:\n',PivotDetail.iloc[:5])
#订单详情表单日菜品成交总额与总数透视表前5行为:
amounts counts
date
2016-08-01 9366.0 233.0
2016-08-02 6125.0 151.0
2016-08-03 6890.0 192.0
2016-08-04 7549.0 169.0
2016-08-05 8671.0 224.0
CrossDetail = pd.crosstab(index=detail['date'],columns=detail['dishes_name'],values=detail['amounts'],aggfunc=np.sum,margins=True)
# 保存为.csv文件
CrossDetail.to_csv('data/CrossDetail.csv',sep=',',index=True)
print('订单详情表单个菜品单日成交总额交叉表后5行5列为:\n',CrossDetail.iloc[-5:,-5:])
#订单详情表单个菜品单日成交总额交叉表后5行5列为:
dishes_name 黄尾袋鼠西拉子红葡萄酒 黄油曲奇饼干 黄花菜炒木耳 黑米恋上葡萄 All
date
2016-08-07 230.0 32.0 105.0 99.0 31306.0
2016-08-08 46.0 NaN NaN 33.0 6532.0
2016-08-09 138.0 NaN 35.0 99.0 7155.0
2016-08-10 46.0 NaN 70.0 33.0 10231.0
All 736.0 80.0 525.0 561.0 125992.0