python-数据框:多层索引数据透视

本文介绍了如何在Python的Pandas库中进行多层数据分组,包括设置日期索引、重采样到月维度以及计算占比。通过示例代码展示了如何处理多层分组后的数据框,使用unstack函数转换行与列的格式,并使用apply函数计算行或列的百分比占比。
摘要由CSDN通过智能技术生成

数据样例

数据样例来自夜曲编程教材案例,下载地址

数据源 链接: https://pan.baidu.com/s/1XQ__n-So0Xu7Zckg3iZ_yg?pwd=wm6w

提取码: wm6w 复制这段内容后打开百度网盘手机App,操作更方便哦

多层分组

多层分组类似excel数据透视表的功能,简单的多层索引就是类似在透视表的行维度上添加字段,首先回顾单层分组的写法:

df.groupby(df['var']).聚合函数()

#单层索引,按category聚合,结果只会聚合数据框中的数值型的字段
groupByCategory=data.groupby(data['category']).sum()】
#输出结果
groupByCategory
#输出结果的索引值
groupByCategory.index

结果如下 

 在单层分组的基础上类推出多层分组的写法

1、先把需要索引的字段组成列表

2、再把列表待人函数中索引值的位置

[df['var1'],df['var'2],df['var3']]

df.groupby([df['var1'],df['var'2],df['var3']]).聚合函数()

#多层索引
groupByCategory=data.groupby([data['date'],data['category']]).sum()
groupByCategory
groupByCategory.index
#三层索引,以此类推
groupByCategory=data.groupby([data['category'],data['date'],data['module']]).sum()
groupByCategory

多层分组重采样

在通过上面的操作对数据进行分组之后,如果我们相对日期进行重采样,把日期为度改为月维度,发现原本的操作会报错

回顾下日期重采样的写法

import pandas as pd
data=pd.read_csv('路径/商场营业额数据.csv',encoding='utf-8')
#将日期从字符串转为时间格式
data['date']=pd.to_datetime(data['date'])
#按日期汇总聚合
group_date=data.groupby(data['date']).sum()#计算sum时,只有数值型的字段会参与计算
#按月重采样
group_month=group_date.resample('M').sum()

按照上面的写法对多层分组的数据框进行重采样会发生如下报错,原因是多层分组之后的数据框是多索引,并不是只有日期索引,所以会报错:TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex, but got an instance of 'MultiIndex'

为了解决这个问题 ,需要先把日期设置为索引,这里注意在设置之前先要保证日期数据是日期格式,因为只有日期格式的索引才能重复,在Pandas中,每个DataFrame(或Series)的行和列都是有唯一的名称的。当你试图对一个带有重复列或行名称的DataFrame进行重新索引时,就会出现”ValueError:cannot reindex from a duplicate axis“的错误。这是因为Pandas无法确定新索引应该分别对应于哪一个重复的名称。

将日期设置为索引之后,在分组聚合中写入其他分组字段分组,再对其使用resample函数进行重采样即可,具体代码如下

import pandas as pd
data=pd.read_csv('/Users/tinawang/Documents/python/数分基础/商场营业额数据.csv',encoding='utf-8')
data["date"] = pd.to_datetime(data["date"])#这一步必不可少
data = data.set_index("date")
groupByCategory = data.groupby(data["category"]).resample("M").sum()
groupByCategory


groupByCategoryModule = data.groupby([data["category"],data['module']]).resample("M").sum()
groupByCategoryModule

输出结果如下:

 把索引调整为行*列格式

上面的分组聚合都是在行上添加维度,如果想转换成行*列格式,就需要使用unstack函数

import pandas as pd
data=pd.read_csv('/Users/tinawang/Documents/python/数分基础/商场营业额数据.csv',encoding='utf-8')
data["date"] = pd.to_datetime(data["date"])#这一步必不可少
data = data.set_index("date")
groupByCategory = data.groupby(data["category"]).resample("M").sum()
groupByCategory

# 使用unstack()函数将groupByCategory按照"category"重新排列
groupByCategory = groupByCategory.unstack("category")

 输出结果如下:

访问多层索引

port pandas as pd
data=pd.read_csv('/Users/tinawang/Documents/python/数分基础/商场营业额数据.csv',encoding='utf-8')
data["date"] = pd.to_datetime(data["date"])#这一步必不可少
data = data.set_index("date")
groupByCategory = data.groupby(data["category"]).resample("M").sum()
#----------------------------------------------------------------------------------
groupByCategory.loc["零售"]

添加行列总计

汇总行数据axis=0
汇总列数据axis=1

添加行总计 

import pandas as pd
data=pd.read_csv('/Users/tinawang/Documents/python/数分基础/商场营业额数据.csv',encoding='utf-8')
data = data.set_index("date")
groupByCategory = data.groupby(data["category"]).resample("M").sum()#重复运行会报错
groupByCategory
result=groupByCategory.unstack("category")
#-----------------------------------------------------------------------
result.sum(axis=1)#汇总列数据,得到每月的营业和综合
result["all"]=result.sum(axis=1)#在原数据框中创建一个all列,放入汇总数据
result#输出结果

输出结果 

 添加列总计

result.sum(axis=0)
result.sum(axis=0).info()#汇总之后的结果是序列数据
result.loc['all']=result.sum(axis=0)#创建一个索引名为all的行,放入汇总后的序列数据
result

输出结果

  

计算占比:apply函数

创建函数def 

使用apply函数将自定义的函数应用到dataframe上,对其行或列进行指定操作

对行操作apply(函数名,axis=0);axis=0是默认值,可省略
对列操作apply(函数名,axis=1)

对行数据计算百分比,本例中,就是计算每个月各个业态营业额占比

计算过程如下: 

#计算占比
import pandas as pd
data=pd.read_csv('/Users/tinawang/Documents/python/数分基础/商场营业额数据.csv',encoding='utf-8')
data = data.set_index("date")
groupByCategory = data.groupby(data["category"]).resample("M").sum()#重复运行会报错
groupByCategory
result=groupByCategory.unstack("category")
result
#------------------------------------------------------------------------------
#计算每个月的商场营业额之和
sumTurnover = result.sum(axis=1)
sumTurnover

#定义一个函数
def getPercentage(item):
    return item / sumTurnover
percentage=result.apply(getPercentage)
percentage=result.apply(getPercentage,axis=0)#在行数据上进行操作
percentage

对列数据进行计算,即计算每个业态在每个月的营业额占比

计算过程 

#计算占比
import pandas as pd
data=pd.read_csv('/Users/tinawang/Documents/python/数分基础/商场营业额数据.csv',encoding='utf-8')
data = data.set_index("date")
groupByCategory = data.groupby(data["category"]).resample("M").sum()#重复运行会报错
groupByCategory
result=groupByCategory.unstack("category")
#---------------------------------------------------------------------------------
sumTurnover = result.sum(axis=0)#计算每个业态的营业额
sumTurnover
#定义一个函数
def getPercentage(item):
    return item / sumTurnover
percentage=result.apply(getPercentage,axis=1)
percentage

  

 最后,如果想计算每个业态每个月的营业额占全年营业额占比怎么计算,最简单的办法是直接除

import pandas as pd
data=pd.read_csv('/Users/tinawang/Documents/python/数分基础/商场营业额数据.csv',encoding='utf-8')
data = data.set_index("date")
groupByCategory = data.groupby(data["category"]).resample("M").sum()#重复运行会报错
#-------------------------------------------------------
groupByCategory.sum()#先计算总和
tem=groupByCategory/groupByCategory.sum()#让数据框中的每个值除以总和
tem.unstack('category')#再重组数据框得到最终样式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值