数据分析之pandas学习笔记(六)(层次化索引、重塑、轴向旋转、行列变换、合并表数据)

level层次化索引

用于数组重塑
以低维度处理高维度数据
基于分组的操作
透视表的生成
pandas的层次化索引示例

unstack()与stack()进行重塑,即:行列索引变换

以DataFrame为例:
df.stack()
降维
列索引最上侧的那一排索引 加到 行索引最右侧
df.unstack()
升维

行索引最右侧的那一竖索引 加到 列索引最上侧

swaplevel()交换两个索引位置

df.swaplevel(0,1)
可以为name,也可以为level索引
在这里插入图片描述

sort_index()排序与 sum(level= )求和排序

df.sort_index(level=0)
对相应维度的那列索引排序
df.sum(level=0)
对行索引求和并自动排序

set_index()和reset_index()索引和列之间相互变换

df.set_index(['c','d'])
将c,d两 --> 变成 --> 行索引

通过添加drop=False字段,会创建出一个新的DataFrame,保留住原来cd这两列的数据。
在这里插入图片描述

df.reset_index()
reset_index的功能跟set_index刚好相反,层次化索引的级别会被转移到列里面
在这里插入图片描述

轴向旋转

重塑(轴向旋转的一种)stack()和unstack()

上面提到了重塑,它其实是轴向旋转的一种
.stack().unstack()操作的都是最内层,在进行轴向旋转的时候,轴级别也会成为结果中的最低级别。
(可以结合上面stack()和unstack()部分的例子。。。体会一下)

轴向旋转pivot()长变宽

df.pivot(index='',columns='',values='')
pandas.DataFrame.pivot()官方文档
将某列作为行索引,某列作为列索引,某(若干)列作为值。
本质有点类似于,先set_index创建层次化索引,然后unstack重塑。

例如下面这样:
在这里插入图片描述

相当于合并同类项(每个value对应的行列索引是唯一的,)
什么意思?看下面这个例子:
在这里插入图片描述但是你用df.pivot_table() 这个方法,就可以避免上述唯一性的问题。

轴向旋转melt()宽变长

pandas.melt()官方文档
官方文档的例子看了几个之后,应该有个大致了解了。但是我看了还是有点不懂,到底有什么实际意义。
它和pivot()的区别只是,在不限定填入值参数的时候,pivot把长的数据变成了宽的数据,melt是把宽数据变成了长数据。

pivot和melt的区别和理解

再仔细考究一下,它们之间的区别,我们来实际体会一下有什么区别。
pivot()
在这里插入图片描述

我们限定了value值区域只填‘baz’

原来的foo列  -->  行索引
原来的bar列  -->	 列索引
原来了baz列  -->	 值区域	 

下面我们不限定值区域:
在这里插入图片描述
可以看到它自动默认把其余列充当值区域显示了。
也就实现了长数据变成了宽数据。
melt()
在这里插入图片描述
感觉看的有点难理解,我们可以大致这样来理解上面生成的结果:

id_vars相当于pivot中的index
value_vars相当于pivot中的columns

当然结果表中并没有把foo和bar这两列变成了行列索引。
而是把foo列作为了一个分组指标,结果中的foo列显示了它的列数据作为分组指标
而bar列,结果中显示了两列,一列纯显示了bar这个列索引名字 一列显示了bar列的具体数据

所以看的时候你可以大致这么看,一行一行对过去看,相当于原表中,one行bar列对应的数据是A,two行bar列对应的数据是B

这样就实现了宽数据变成了长数据

当然你想将baz和zoo列也一起放进来,那么value_var参数字段中添加即可,这样显示的结果表会变得更长
当然melt()过后的表格想恢复成原来的样子,可以直接在melt()后的df对象直接用pivot()即可
就像下面这样:
大致可以恢复成原来的数据表样式
因为我melt的时候拿了原数据表的2列数据,所以pivot的时候也只恢复了2列,看去没有恢复成原表所有数据,但是样式做到了和原表差不多的样式。

如果你一定要恢复成原表的样式的话,可以这样做:

1,将pivot后的df对象(这里我叫做b好了),先b.columns.name=None
2, 再用reset_index即可。
(可能排好之后的顺序不是你期望的那样,如果你原表是有序的你可以再sort_values(by=[…])对(若干)列里的值,排序一下)

在这里插入图片描述

pivot_table()数据透视表

pandas.pivot_table()官方文档
参数详解,这一篇写的很详细很好~

pd.pivot_table(df,index=[..],
				  columns=[..],
				  values=[..],
				  aggfunc=[..],   -->np.sum,np.mean或字典(实现不同values执行不同函数)
				  fill_value=0,
				  margins=True,   -->总和数据
				  
)

在这里插入图片描述
在这里插入图片描述

pivot_table()高级用法

table = pd.pivot_table(df,index=["Manager","Status"],columns=["Product"],values=["Quantity","Price"],
               aggfunc={"Quantity":len,"Price":[np.sum,np.mean]},fill_value=0)
table

在这里插入图片描述类似SQL查询一样
在这里插入图片描述

groupby()分组

pandas.groupby()官方文档
场景应用

df.groupby([..],
			axis=,
			level=,
			sort=,
			
			
)

对哪一列进行分组,就把那一列作为行索引:
在这里插入图片描述有多层次的索引的话,也可以直接对分组出所需要的分组。
在这里插入图片描述

pivot和melt和pivot_table和groupby小结

pivot还行
melt不常用
pivot_table数据透视表,功能强大
groupby分组

合并表数据

join()

join的方法要求:
1,索引相似或相同
2,无重叠的列
3,默认左连接

df_left.join(df_right,
			 on='',
			 how=''  可填inner,left,right,outer
			 )
			 
merge()
df01.merge(df02)
pd.merge(df01,df02)		默认将重叠的列当做键(有点类似于SQL中的外键),默认内连接inner(用how参数申明)

df01.merge(df02,
		   on='',	最好加这个字段申明一下要连接的列是哪(几)个
		   how='inner',	默认是内连接inner,此外还有left左外连接,right右外连接,outer外连接
		   suffixes=('_left','_right')	可实现重复列名的重命名
		   left_index=True	将行索引用于连接键
		   right_index=True  将行索引用于连接键
		   sort=True	排序字段,默认为True

)

当出现多对多的情况时,由于多对多结果产生的是行笛卡尔积,所以on参数需要传入多个连接键进行连接。
concat()

pandas.concat()官方文档
详细用法

combine_first()

pandas.Series.combine_first官方文档
pandas.DataFrame.combine_first官方文档
pandas中concatenate和combine_first的用法

实践应用

场景一

将如下表,改成学号id,学生,各门学科,各门学科中的排名。
在这里插入图片描述
改成这样
在这里插入图片描述
首先,它肯定进行了rank排名操作,肯定进行了行列变换,或许会用到表合并,列与列的位置调换等相关操作。

下面一起来动手操作吧~

原始数据
df = pd.DataFrame({
    # 'id':[001,002,003,001,002,003],   这样写会报错,理由是:数字前不能有多个0
    # 'score':[90,96,93,87,82,80],
    # 'subjectCode':[01,01,01,02,02,02],  这样写会报错,理由是:数字前不能有多个0
    'id': ['001', '002', '003', '001', '002', '003'],
    'score': [90, 96, 93, 87, 82, 80],
    'subjectCode': ['01','01', '01', '02', '02', '02'],
    'subjectName':['语文','语文','语文','数学','数学','数学'],
    'userName':['张三','李四','王五','张三','李四','王五']
})

在这里插入图片描述

步骤一

利用povit(),截取userName和subjectName列作为行和列,score作为值。

df01 = df.pivot(index='userName',columns='subjectName',values='score')

在这里插入图片描述

步骤二

去掉列索引的name -->即:去除上面subjectName字段

# df01.index.name=None
df01.columns.name=None
步骤三

在df01表新建一列数学排名列
method=first(如果排名相同,取前一个排名进一位,当然你可以不填这个字段,那么排名不是取整,而有0·5·产生,不过这样也没事,看你个人需求,)
astype(‘int64’)是因为,排名出的结果是float64形式展示的,看着很别扭,我要排名全取整。
在df01表新建一列语文排名列

df01['数学rank'] = df01['数学'].rank(method='first').astype('int64')
df01['语文rank'] = df01['语文'].rank(method='first').astype('int64')
步骤四

我这里其实做了两步:
1,通过reindex(…),重新调整了一下,列与列之间的位置
2,通过reset_index(),把userName这一列行索引,重整到列里面

df01 = df01.reindex(['数学','数学rank','语文','语文rank'],axis=1).reset_index()

在这里插入图片描述

步骤五

我这里其实做了两步:

1,合并表数据
合并的方法有很多(merge、join、concat、combine_first)如果是直接拼到最右边,那直接join(要拼的列)

但是我这里要拼到最左侧,join方法行不通,不能达到我们想要的效果

我这里通过merge()函数来实现,因为要DataFrame对象才有merge方法,所以df[‘id’].merge()是会报错的!

2,去重
因为df01表的数据,只有3行,但拼上去的id列有6行数据,这样在进行左连接还是右连接时肯定会多出来3行重复数据,或者匹配不到数据,

匹配不到数据的话就是NaN数据缺失那么就要用dropna() 方法了

但是,这里只是数据重复,不是数据缺失,
所以可以用drop_duplicates() 方法对DataFrame对象的某一列进行操作,keep=first意思是保留第一条重复的数据,不保留其余重复数据。

df01 = df[['id','userName']].merge(df01,on='userName',how='left').drop_duplicates(['id'],keep='first')

在这里插入图片描述

场景二

如果你想类似于Excel那样,透视表操作的话,看这篇,写的很好:

参考这篇,pivot_table透视表的实际应用,

场景三

如果你想简单的可视化的话,可以瞧瞧这个样例,可能不是很好:

参考这篇,groupby的实际应用,涉及到数据可视化的简单展示

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值