查看原文
其他

详解pd.DataFrame中的几种索引变换

luanhz 小数志 2022-07-01

导读

pandas中最常用的数据结构是DataFrame,而DataFrame相较于嵌套list或者二维numpy数组更好用的原因之一在于其提供了行索引和列名。本文主要介绍行索引的几种变换方式,包括rename与reindex、index.map、set_index与reset_index、stack与unstack等。


惯例开局一张图


01 索引简介与样例数据

Series和DataFrame是pandas中的主要数据结构类型(老版本中曾有三维数据结构Panel,是DataFrame的容器,后被取消),而二者相较于传统的数组或list而言,最大的便利之处在于其提供了索引,DataFrame中还有列标签名,这些都使得在操作一行或一列数据中非常方便,包括在数据访问、数据处理转换等。关于索引的详细介绍可参考前文:python数据科学系列:pandas入门详细教程


这里,为了便于后文举例解释,给出基本的DataFrame样例数据如下:


后文将以此作为操作对象,针对索引的几种常用变换进行介绍。

注:这里的索引应广义的理解为既包扩行索引,也包括列标签。



02 reindex和rename

学习pandas之初,reindex和rename容易使人混淆的一组接口,就其具体功能来看:

  • reindex执行的是索引重组操作,接收一组标签序列作为新索引,既适用于行索引也适用于列标签名,重组之后索引数量可能发生变化,索引名为传入标签序列

  • rename执行的是索引重命名操作,接收一个字典映射或一个变换函数,也均适用于行列索引,重命名之后索引数量不发生改变,索引名可能发生变化


另外二者执行功能和接收参数的套路也是很为相近的,均支持两种变换方式:

  • 一种是变换内容+axis指定作用轴(可选0/1或index/columns);

  • 另一种是直接用index/columns关键字指定作用轴


具体而言,reindex执行索引重组操作,以新接收的一组标签序列作为索引,当原DataFrame中存在该索引时则提取相应行或列,否则赋值为空或填充指定值。对于前面介绍的示例数据df,以重组行索引为例,两种可选方式为:


注意到原df中行索引为[1, 3, 5],而新重组的目标索引为[1, 2, 3],其中[1, 3]为已有索引直接提取,[2, 4]在原df中不存在,所以填充空值;同时,原df中索引[5]由于不在指定索引中,所以遭舍弃。进一步地,由于重组后可能存在空值,reindex提供了填充空值的可选参数fill_value和method,二者用法与fillna方法一致,前者用于指定固定值填充,后者用于指定填充策略,例如:


rename用法套路与reindex很为相近,但执行功能完全不同,主要用于执行索引重命名操作,接收一个字典或一个重命名规则的函数类型,示例如下:



03 index.map

针对DataFrame中的数据,pandas中提供了一对功能有些相近的接口:map和apply,以及applymap,其中map仅可用于DataFrame中的一列(也即即Series),可接收字典或函数完成单列数据的变换;apply既可用于一列(即Series)也可用于多列(即DataFrame),但仅可接收函数作为参数,当作用于Series时对每个元素进行变换,作用于DataFrame时对其中的每一行或每一列进行变换;而applymap则仅可作用于DataFrame,且作用对象是对DataFrame中的每个元素进行变换。也就是说,三者的最大不同在于作用范围以及变换方式的不同。


实际上,apply和map还有一个细微区别在于:同样是可作用于单列对象,apply适用于索引这种特殊的单列,而map则不适用。所以,对索引执行变换的另一种可选方式是用map函数,其具体操作方式与DataFrame常规map操作一致,接收一个函数作为参数即可:



04 set_index与reset_index
set_index和reset_index是一对互逆的操作,其中前者用于置位索引——将DataFrame中某一列设置为索引,同时丢弃原索引;而reset_index用于复位索引——将索引加入到数据中作为一列或直接丢弃,可选drop参数。二者是非常常用的一组操作,例如在执行groupby操作后一般会得到一个series类型,此时增加一个reset_index操作即可实现series转换为DataFrame。当然转换的操作不止这一种。



05 stack与unstack

这也是一对互逆的操作,其中stack原义表示堆叠,实现将所有列标签堆叠到行索引中;unstack即解堆,用于将复合行索引中的一个维度索引平铺到列标签中。实际上,二者的操作即是SQL中经典的行转列与列转行,也即在长表与宽表之间转换。


当然,实现unstack操作的方式还有pivot,此处不再展开。


相关阅读:


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存