首页 > pandas 阅读数:38

pandas层级索引

pandas 有 Series 和 DataFrame 两种数据结构,它们分别用于处理一维数据和二维数据。但是在实际应用中经常会遇到多维数据的情况,为了处理多维数据,可使用层级索引,将高维数据转化为类似一维 Series 和二维 DataFrame 对象的形式。

层级索引就是对索引进行层次化分类,该索引既可以是行索引,也可以是列索引。层级索引是 pandas 的一项重要功能,它能在一个轴上拥有多个(两个以上)索引级别。利用层级索引可实现以低维度形式处理高维度数据。

1. 创建层级索引

1) 创建 Series 的层级索引

常用的方法就是给 Series() 构造函数的 index 参数传递两个数组。例如,创建一个由整数与文字组成的层级索引,其示例代码如下。
In [1]:  import pandas as pd
In [2]:  se=pd.Series(['电视机',2300,'空调',1980],index=[[1,1,2,2],['product','price','product','price']])
In [3]:  se
Out[3]:  1   product     电视机
             price      2300
         2   product      空调
             price       1980
         dtype: object

2) 创建 DataFrame 的层级索引

① 隐式构造层级索引

常用的方法就是给构造函数 DataFrame() 的 index 或 columns 参数传递两个或两个以上的数组。

例如,创建一个包含品牌、产品类型、价格和折扣率的产品信息 DataFrame 对象,该 DataFrame 的行索引中就包含品牌与产品类型的层级索引,其示例代码如下。
In [4]:  import numpy as np
In [5]:  from pandas import DataFrame,Series
In [6]:  data = np.array([[2300,1.00],[1980,1.00],[3600,0.96],[2100,0.98]])
In [7]:  df = DataFrame(data,columns=['价格','折扣率'],index=[['格力','格力','TCL','TCL'],['电视机','空调','电视机','空调']])
In [8]:  df
out[8]:                  价格  折扣率
         格力  电视机 2300.0   1.00
                 空调 1980.0   1.00
         TCL   电视机 3600.0   0.96
                 空调 2100.0   0.98

层级索引(MultiIndex)继承于 Index,是多级索引的对象。MultiIndex 有 levels 和 labels 两个信息。levels 表示每个层级中分别有哪些标签,labels 是每个标签的下标。利用 levels 属性可获取索引中每一级的标签,而用 labels 属性可获取标签的下标。还可以使用 get_loc() 和 get_indexer() 来获取单个和多个标签的下标。

以产品信息 DataFrame 实例 df 为例,获取 df 标签的下标,其示例代码如下。
In [9]:  mindex = df.index    #MultiIndex对象
In [10]:  mindex[0:4]
Out[10]:  MultiIndex(levels=[['TCL','格力'],['电视机','空调']],labels=[[1, 1, 0, 0], [0, 1, 0, 1]])
In [11]:  mindex.levels[0]
Out[11]:  Index(['TCL','格力'], dtype='object')
In [12]:  mindex.labels[0]
Out[12]:  FrozenNDArray([1, 1, 0, 0], dtype='int8')
In [13]:  mindex.get_loc(('格力','电视机'))
Out[13]:  0
In [14]:  mindex.get_indexer([('格力','电视机'),('TCL','空调'),'nothing'])
Out[14]:  array([ 0,  3, -1], dtype=int64)

② 显式构造pd.MultiIndex

显式构造 pd.MultiIndex 就是使用以 from_ 开头的 MultiIndex 类方法,从特定的数据结构创建 MultiIndex 对象。以创建产品信息的层级索引为例,其示例代码如下。

  • 使用 from_arrays() 方法,从多个数组创建 MultiIndex 对象。

df_arrays = DataFrame(
    data,columns=['价格','折扣率'],
    index=pd.MultiIndex.from_arrays([
        ['格力','格力','TCL','TCL'], 
        ['电视机','空调','电视机','空调']
    ])
)


  • 使用 from_tuples() 方法,从多个元组创建 MultiIndex 对象。

df_tuples = DataFrame(
     data,columns=['价格','折扣率'],
     index=pd.MultiIndex.from_tuples([
             ('格力','电视机'),('格力','空调'),('TCL','电视机'),('TCL','空调')
     ])
)


  • 使用 from_product() 方法,利用多个集合的笛卡尔积创建 MultiIndex 对象。

df_product = DataFrame(
     data,columns=['价格','折扣率'],
     index=pd.MultiIndex.from_product([
     ['格力','TCL'], ['电视机','空调']
     ])
)

2. 层级索引对象的元素选择

1) Series 的元素选择

通过中括号([ ])的索引和切片操作可获取单个或多个元素,或使用 loc 与 iloc 同样也能获取单个或多个元素,其示例代码如下。
In [15]:  se[[2,'price']]
Out[15]:  2  product      空调
             price      1980
          dtype: object
In [16]:  se[2]['price']
Out[16]:  1980
In [17]:  se.iloc[1:2]
Out[17]:  1  price    2300
          dtype: object

2) DataFrame 的元素选择

① 直接使用列名称选择 1 列元素,例如 df['价格'],表示选择“价格”这 1 列元素。

② 使用中括号([ ])或 iloc() 函数的切片操作可选择 1 行或多行元素。如 df[0:1] 与 df.iloc[0:1] 选择是行索引为“0”的这 1 行元素,而 df[0:3] 与 df.iloc[0:3] 选择的是行索引为“0”“1”“2”的这 3 行元素。

③ 使用行索引切片和列名称组合可选择某个范围的元素,如 df[0:2]['价格']。

其示例代码如下。
In [18]:  df['价格']
Out[18]:  格力  电视机    2300.0
                  空调     1980.0
          TCL   电视机    3600.0
                  空调     2100.0
          Name: 价格, dtype: float64
In [19]:  df[0:1]
Out[19]:
                         价格     折扣率
          格力  电视机  2300.0       1.0
In [20]:  df[0:2]['价格']
Out[20]:  格力  电视机  2300.0
                 空调   1980.0
          Name: 价格, dtype: float64

3. 调整层级索引间的顺序

首先指定层级索引中每一层索引的名称,然后再使用 swaplevel() 函数来调整层级索引间的顺序,其示例代码如下。
In [21]:  df.index.names = ['key1','key2']
In [22]:  df.swaplevel('key1','key2')
Out[22]:
                           价格  折扣率
           key2  key1
          电视机  格力     2300.0   1.00
            空调  格力     1980.0   1.00
          电视机   TCL     3600.0   0.96
            空调   TCL     2100.0   0.98

4. 对某级别索引排序

使用 sort_index(level) 函数来实现对某级别索引的排序,其示例代码如下。
In [23]:  df.sort_index(level=1)
Out[23]:
                             价格   折扣率
          key1    key2
           TCL   电视机     3600.0   0.96
           格力  电视机     2300.0   1.00
           TCL    空调      2100.0   0.98
           格力   空调      1980.0   1.00

5. 根据某级别索引进行汇总

使用 sum(level,axis) 函数可根据某级别索引进行汇总,其示例代码如下。
In [24]:  df.sum(level=1,axis=0)
Out[24]:
                               价格  折扣率
           key2
          电视机             5900.0   1.96
            空调             4080.0   1.98

6. 指定 DataFrame 的列为索引或还原索引列

使用 set_index() 函数可指定 DataFrame 的列为索引,而使用 reset_index() 函数可还原索引列,其示例代码如下。
In [25]:  df.reset_index()
Out[25]:
             key1    key2    价格  折扣率
          0   格力   电视机 2300.0    1.00
          1   格力     空调 1980.0    1.00
          2   TCL    电视机 3600.0    0.96
          3   TCL      空调 2100.0    0.98
In [26]:  df.set_index('价格')
Out[26]:

             价格   折扣率
          2300.0    1.00
          1980.0    1.00
          3600.0    0.96
          2100.0    0.98