完整版Pandas 层级索引
Posted ZSYL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了完整版Pandas 层级索引相关的知识,希望对你有一定的参考价值。
Pandas 层级索引
Pandas数据结构中最常用的是Series和DataFrame,它们分别用于处理一维数据和二维数据。但我们也经常遇到存储多维数据的需求,数据索引超过一两个键,这种情况下的数据超出了上面两种数据结构能够表示的范围,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 层级索引的主要内容,如果未能解决你的问题,请参考以下文章