python读取多级表头_python之Dataframe:多级表头和索引灵
活的处理(⼀)
DataFrame俗称数据框,和⼀般的Excel表格没有多⼤区别,⼀般包含索引(⾏)和表头(列),在python中,由pandas包提供。
这是⼀个最简单的数据框类型,只包含⼀级索引和⼀级表头
如果你的python还没有这个包,请执⾏以下命令安装:
pip install pandas
这⼀节,我们要处理的主题是:多级表头和多级⽬录
先看看他们长什么样⼦:
表格1:包含⼆级表头和⼀级索引
表格⼆:包含⼆级索引和⼀级表头
在Excel⾥⾯看这些表格,还没什么特别的感觉,但是,今天我们要在python中来处理这样的表格,下⾯就开始吧!先说⼀下内容⼤概:
1. 如何构造多级表格
多级表格,常来⾃于实际的需要,许多时候,我们的数据并不是单⼀的表现形式,会有对⽐、计算、时间序列等因素。我先给出两个⼀级表格(也就是我们数据的原始形式)。
⽇期 渠道 ⽤户数 会话数 唯⼀⾝份浏览量
0 20180607 (Other) 3839 7324 15223
1 20180607 Direct 30060 35364 72330
2 20180607 Display 2 2 2
3 20180607 Organic Search 50636 57410 144043
4 20180607 Referral 284
5 3370 8380
5 20180607 Social 1310 1564 3480
6 2018060
7 shareasale 214 23
8 568
⽇期 渠道 ⽤户数 会话数 唯⼀⾝份浏览量
0 20180531 (Other) 3756 6351 13825
1 20180531 Direct 33195 3881
2 78479
2 20180531 Display 2 2 2
3 20180531 Email 1 1 3
4 20180531 Organic Search 56003 64026 158187
5 20180531 Referral 3185 3769 9252
6 20180531 Social 3380 3690 7698
7 20180531 shareasale 241 268 658
你需要将这个表格⽂件下载下来,使⽤pandas包的read_excel()函数读⼊。
这2个数据表格分别是2018年6⽉7号各个渠道的流量数据以及上周同期的数据,我们的⽬的是要做对⽐,把这2个表格的数据放到⼀起,⽅便对⽐查看。但我们⽤脑袋想⼀下,最⽅便对⽐的数据应该是什么样的呢?
前⾯我们已经给出了2个⽰例,分别是2级表头和2级索引,其实都起到了对⽐的作⽤。下⾯,我们就分别讲⼀下这2个表格是怎么做出来的。
1.1 我们先来构建多级表头,如下这样格式
表格1:包含⼆级表头和⼀级索引
导⼊包,读⼊数据
import pandas as pd
from pandas import DataFrame
channel = pd.read_excel('处理多级表格-⽰例数据.xlsx',sheetname=0)
channel_last_week = pd.read_excel('处理多级表格-⽰例数据.xlsx', sheetname=1)
⼀般pandas包导⼊后会给个pd的别名。读⼊xlsx格式的数据使⽤函数pd.read_excel(),第⼀个参数是⽂件所在路径, 参数sheetname是指读⼊这个⼯作簿当中的哪个sheet,这⾥有2种写法:第⼀种是给出sheet的索引号(从左⾄右从0开始计数),第⼆种是给出sheet的具体名称,⽐如:
channel = pd.read_excel('处理多级表格-⽰例数据.xlsx',sheetname='20180607')
我们先讲⼀种最常规的⽅法:拼接法
显然,我们有三个指标是需要对⽐的:⽤户数、会话数、唯⼀⾝份浏览量
所以,我们先把渠道设置为索引,使⽤函数set_index()
channel.set_index('渠道', inplace=True)
channel_last_week.set_index('渠道', inplace=True)
注:在pandas中,⼀般set_xxx类型的函数都会有⼀个参数inplace,代表是在原对象上修改,还是返回⼀个新的对象。
这时候,我们的channel就变成了下⾯这样
image.png
我们来看⼀下它的index和columns
channel.index
Out[74]: Index(['(Other)', 'Direct', 'Display', 'Organic Search', 'Referral', 'Social', 'shareasale'], dtype='object', name='渠道')
Out[75]: Index(['⽇期', '⽤户数', '会话数', '唯⼀⾝份浏览量'], dtype='object')
如果细⼼的朋友⼀定会发现,index和columns的值其实都是属于同⼀个类: indexes.base.
Index
lumns)
Out[76]: indexes.base.Index
type(channel.index)
Out[77]: indexes.base.Index
现在来看这个⽇期,它⾥⾯的值应该是作为表头的,⽤来对⽐三个指标,所以,这⾥我们可以索性把它从columns中删除掉,到时候直接把它的值拿出来备⽤
yd,yd_la = '20180607','20180531'
channel.drop('⽇期', axis=1, inplace=True)
channel_last_week.drop('⽇期', axis=1, inplace=True)
第⼀⾏中两个变量间加逗号的写法,是⼀⾏同时实现2个及以上变量赋值的快捷写法,按顺序⼀⼀对应。
可能有⼈会说,我直接输⼊⽇期字符串会显得不够⾃动化和程序化,万⼀哪天传⼊的数据⾥⾯⽇期不是这两个呢?
其实你也可以使⽤如下的⽅法获取
yd,yd_la = channel.iloc[0,0],channel_last_week.iloc[0,0]
iloc是根据位置进⾏切⽚选择的,你也可以使⽤键名称和索引名称选择
yd,yd_la = channel['⽇期']['Organic Search'],channel_last_week['⽇期']['Organic Search']
另外,删除列,除了使⽤drop外,还可以直接这样操作
del channel['⽇期']
这种写法我直接在原对象上删除,不像drop还可以选择返回删除后的新对象(不影响原对象)
drop除了可以删除列,还可以删除⾏,只需要设置axis=0(默认),输⼊索引值即可,⽐如
channel.drop('Direct')
删除了索引值为Direct的⾏。
python怎么读入excel现在我们的channal对象是这样的了
image.png
开始构造,最直观的做法就是把两个表中同⼀个指标的数据合并在⼀起,并且将⽇期作为底层表头,指标作为第⼆层表头
DataFrame的合并函数有好⼏个:merge(基于column名称)、append、concat(基于index的值)…这⾥我们选择concat.
df_user = pd.concat([channel_last_week['⽤户数'], channel['⽤户数']],
keys=[yd_la, yd], axis=1).fillna(0)
先看⼀下结果:
image.png
请忽略⼩数(显⽰问题)。可以看到,左边是上周同期的,右边是6⽉7号的。
concat的参数:
第⼀个list类型,元素是要合并的DataFrame;
keys起到的作⽤是,其值作为合并后新DataFrame的列名,axis=1的作⽤是横着合并(等于0的时候代表* 竖这合并,相当于拼接在下⽅);
最后有个fillna函数,是因为如果有出现索引对不齐的情况,则会匹配出NA值(⽐如Email这个索引值就不是都有,匹配后20180607这列的值就为0)
最后成型
有了上⾯的合并经验,我们可以把上⾯的那个合并结果作为⼀个整体,然后对每⼀个columns指标都做同样的事情,最后合并起来,其keys的值就是原columns的值,如下所⽰:
df_session = pd.concat([channel_last_week['会话数'], channel['会话数']],
keys=[yd_la, yd], axis=1).fillna(0)
df_uv = pd.concat([channel_last_week['唯⼀⾝份浏览量'], channel['唯⼀⾝份浏览量']],
keys=[yd_la, yd], axis=1).fillna(0)
channel_together = pd.concat([df_user,df_session,df_uv],keys=['⽤户数', '会话数', '唯⼀⾝份浏览量'],axis=1).fillna(0)
最后来看我们的channel_together 长什么样
Out[119]:
⽤户数 会话数 唯⼀⾝份浏览量
20180531 20180607 20180531 20180607 20180531 20180607
(Other) 3756 3839 6351 7324 13825 15223
Direct 33195 30060 38812 35364 78479 72330
Display 2 2.0 2 2 2 2
Email 1 0.0 1 0 3 0
Organic Search 56003 50636.0 64026 57410 158187 144043
Referral 3185 2845 3769 3370 9252 8380
Social 3380 1310 3690 1564 7698 3480
shareasale 241 214 268 238 658 568
将其输出到Excel中就是⽬标中的那种格式啦!但是,你这个代码未免有点过长了,⽽且类似的代码⽐较多,现在,我们使⽤列表推导式,重新得到channel_together
发⼤招啦~~~
channel_together = pd.concat([
for column in ['⽤户数', '会话数', '唯⼀⾝份浏览量']], axis=1, keys=['⽤户数', '会话数', '唯⼀⾝份浏览量']).fillna(0)
看到没有,⼀句代码就解决!
未完待续~~~~

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。