Pandas学习笔记五——Pandas学习——层级索引

Pandas学习——层级索引

pandas数据结构中最常用的是Series和DataFrame,它们分别用于处理一维数据和二维数据。但我们也经常遇到存储多维数据的需求,数据索引超过一两个键,这种情况下的数据超出了上面两种数据结构能够表示的范围,Pandas提供了Panel和Panel4D对象来解决三维数据和四维数据。而实践中,更直观的形式是通过层级索引,配合多个不同等级(level)的一级索引一起使用,这样就可以将高维数组转化为类似一维Series和二维DataFrame对象的形式。

创建层级索引的数据结构

我们先来看个通过层级索引将DataFrame数据转化为Series数据结构的例子:

import numpy as np
import pandas as pd
#创建一个DataFrame对象
data = [[33871648, 37253956],
        [18976457, 19378102],
        [20851820, 25145561]]
pop = pd.DataFrame(data,columns=[2000, 2010],index=['California', 'New York', 'Texas'])
pop

Out[30]: 
                2000      2010
California  33871648  37253956
New York    18976457  19378102
Texas       20851820  25145561


#通过层级索引创建一个与上面DataFrame等价的Series
data_1 = [33871648, 37253956, 18976457, 19378102, 20851820, 25145561]
#通过两个索引的笛卡尔积,创建MultiIndex对象
index_1 = pd.MultiIndex.from_product([['California', 'New York','Texas'],[2000, 2010]])
df = pd.Series(data_1, index=index_1)
df

Out[32]: 
California  2010    33871648
            2010    37253956
New York    2010    18976457
            2010    19378102
Texas       2010    20851820
            2010    25145561
dtype: int64

层级索引最大的作用在于能够将超过二维的数据结构转化为等价的DataFrame,下面展示将四维的数据通过行多层索引(2层)和列多层索引(2层)进行降维

#多级行列索引,并为每项索引分别命名
index = pd.MultiIndex.from_product([[2013, 2014],[1, 2]], names=['year', 'visit'])
columns = pd.MultiIndex.from_product([['Bob', 'Duido', 'Sue'],['HR', 'Temp']],
                                     names=['subject', 'type'])

#模拟数据
data = np.round(np.random.randn(4,6), 1)
data[:, ::2] *= 10
data += 37

#创建DataFrame
health_data = pd.DataFrame(data, index=index, columns=columns)
health_data

Out[37]: 
subject      Bob       Duido         Sue      
type          HR  Temp    HR  Temp    HR  Temp
year visit                                    
2013 1      27.0  37.2  32.0  36.8  21.0  37.1
     2      29.0  36.9  17.0  38.1  22.0  37.2
2014 1      33.0  36.9  26.0  37.1  22.0  36.0
     2      29.0  38.2  36.0  35.9  23.0  38.5
#使用unstack()方法可以将层次索引的数据结构转化为一个普通的DataFrame,stack()方法作用相反
health_data.unstack()

Out[48]: 
subject   Bob                   Duido  ...          Sue                  
type       HR        Temp          HR  ...   Temp    HR        Temp      
visit       1     2     1     2     1  ...      2     1     2     1     2
year                                   ...                               
2013     27.0  29.0  37.2  36.9  32.0  ...   38.1  21.0  22.0  37.1  37.2
2014     33.0  29.0  36.9  38.2  26.0  ...   35.9  22.0  23.0  36.0  38.5

[2 rows x 12 columns]

多级索引的取值和切片

#这里已上文得到的health_data做为实验对象
#选取Sue的心率速度
health_data['Sue', 'HR']

Out[77]: 
year  visit
2013  1        21.0
      2        22.0
2014  1        22.0
      2        23.0
Name: (Sue, HR), dtype: float64
#如果想要对health_data多个维度进行切片,可以使用pands提供的loc、iloc索引器
#使用iloc索引器
health_data.iloc[:2, :2]

Out[83]: 
subject      Bob      
type          HR  Temp
year visit            
2013 1      27.0  37.2
     2      29.0  36.9

#使用loc索引器
health_data.loc[2013, ('Bob','HR')]

Out[88]: 
visit
1    27.0
2    29.0
Name: (Bob, HR), dtype: float64

#直接使用上面的两种索引器跳过行或列的第一级索引对第二索引进行切片会发生报错,使用IndexSlice对象,可以解决这个问题
idx = pd.IndexSlice
health_data.loc[idx[:, 1], idx[:, 'HR']]

Out[94]: 
subject      Bob Duido   Sue
type          HR    HR    HR
year visit                  
2013 1      27.0  32.0  21.0
2014 1      33.0  26.0  22.0

多级索引的数据累计方法

#Pandas自带了一些数据累计方法,比如mean(),sum(),max(),对于层级索引器,可以设置参数level实现对数据子集的累计操作
#计算各项指标每年的平均值
data_mean = health_data.mean(level='year')
data_mean

Out[100]: 
subject   Bob        Duido          Sue       
type       HR   Temp    HR   Temp    HR   Temp
year                                          
2013     28.0  37.05  24.5  37.45  21.5  37.15
2014     31.0  37.55  31.0  36.50  22.5  37.25

#计算每一年所有人的平均心率和体温
data_mean.mean(axis=1, level='type')
Out[103]: 
type         HR       Temp
year                      
2013  24.666667  37.216667
2014  28.166667  37.100000

猜你喜欢

转载自blog.csdn.net/jasonzhoujx/article/details/81638034