完整版Pandas 层级索引

Posted ZSYL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了完整版Pandas 层级索引相关的知识,希望对你有一定的参考价值。

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

1. 创建层级索引的数据结构

我们先来看个通过层级索引将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]

2. 多级索引的取值和切片

# 这里已上文得到的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

3. 多级索引的数据累计方法

# 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

4. 层级索引(hierarchical indexing)

下面创建一个Series, 在输入索引Index时,输入了由两个子list组成的list,第一个子list是外层索引,第二个list是内层索引。

示例代码:

import pandas as pd
import numpy as np

ser_obj = pd.Series(np.random.randn(12),index=[
                ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd'],
                [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]
            ])
print(ser_obj)

运行结果:

a  0    0.099174
   1   -0.310414
   2   -0.558047
b  0    1.742445
   1    1.152924
   2   -0.725332
c  0   -0.150638
   1    0.251660
   2    0.063387
d  0    1.080605
   1    0.567547
   2   -0.154148
dtype: float64

4.1 MultiIndex索引对象

  • 打印这个Series的索引类型,显示是MultiIndex

  • 直接将索引打印出来,可以看到有lavels,和labels两个信息。levels表示两个层级中分别有那些标签,labels是每个位置分别是什么标签。

示例代码:

print(type(ser_obj.index))
print(ser_obj.index)

运行结果:

<class 'pandas.indexes.multi.MultiIndex'>
MultiIndex(levels=[['a', 'b', 'c', 'd'], [0, 1, 2]],
           labels=[[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3], [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]])

4.2 选取子集

  • 根据索引获取数据。因为现在有两层索引,当通过外层索引获取数据的时候,可以直接利用外层索引的标签来获取。

  • 当要通过内层索引获取数据的时候,在list中传入两个元素,前者是表示要选取的外层索引,后者表示要选取的内层索引。

1. 外层选取:

ser_obj[‘outer_label’]

示例代码:

# 外层选取
print(ser_obj['c'])

运行结果:

0   -1.362096
1    1.558091
2   -0.452313
dtype: float64

2. 内层选取:

ser_obj[:, ‘inner_label’]

示例代码:

# 内层选取
print(ser_obj[:, 2])

运行结果:

a    0.826662
b    0.015426
c   -0.452313
d   -0.051063
dtype: float64

常用于分组操作、透视表的生成等


4.2 交换分层顺序

swaplevel()

.swaplevel( )交换内层与外层索引。

示例代码:

print(ser_obj.swaplevel())

运行结果:

0  a    0.099174
1  a   -0.310414
2  a   -0.558047
0  b    1.742445
1  b    1.152924
2  b   -0.725332
0  c   -0.150638
1  c    0.251660
2  c    0.063387
0  d    1.080605
1  d    0.567547
2  d   -0.154148
dtype: float64

4.3 交换并排序分层

sortlevel()

.sortlevel( )先对外层索引进行排序,再对内层索引进行排序,默认是升序。

示例代码:

# 交换并排序分层
print(ser_obj.swaplevel().sortlevel())

运行结果:

0  a    0.099174
   b    1.742445
   c   -0.150638
   d    1.080605
1  a   -0.310414
   b    1.152924
   c    0.251660
   d    0.567547
2  a   -0.558047
   b   -0.725332
   c    0.063387
   d   -0.154148
dtype: float64

加油!

感谢!

努力!

以上是关于完整版Pandas 层级索引的主要内容,如果未能解决你的问题,请参考以下文章

Pandas的函数应用层级索引统计计算

pandas分层索引(层级索引MultiIndex)的创建取值切片统计计算以及普通索引和层级索引的转换方法

MySQL优化(超完整版)

pandas层次化索引

pandas层次化索引

完整版断点续传秒传,支持超大大大文件_支持重定义文件名和路径