3.6 层级索引
当遇到多维数据,数据索引超过一两个键,可通过层级索引(也叫多级索引)配合多个有不同等级的一级索引一起使用。
import numpy as np
import pandas as pd
3.6.1 多级索引Series
如何用一维的Series对象表示二维数据
笨办法
用元组表示索引
index = [('California', 2000), ('California', 2010),
('New York', 2000), ('New York', 2010),
('Texas', 2000), ('Texas', 2010)]
populations = [33871648, 37253956,
18976457, 19378102,
20851820, 25145561]
pop = pd.Series(populations, index=index)
pop
(California, 2000) 33871648 (California, 2010) 37253956 (New York, 2000) 18976457 (New York, 2010) 19378102 (Texas, 2000) 20851820 (Texas, 2010) 25145561 dtype: int64
# 通过元组构成的多级索引,直接取值或切片
pop[('California', 2010):('Texas', 2000)]
(California, 2010) 37253956 (New York, 2000) 18976457 (New York, 2010) 19378102 (Texas, 2000) 20851820 dtype: int64
# 不方便直接获得元组中的项的所有数据,如2010年的所有数据
pop[[i for i in pop.index if i[1] == 2010]]
(California, 2010) 37253956 (New York, 2010) 19378102 (Texas, 2010) 25145561 dtype: int64
好办法:Pandas多级索引
pd可以用元组创建多级索引:MultiIndex类型
index = pd.MultiIndex.from_tuples(index)
index
MultiIndex(levels=[['California', 'New York', 'Texas'], [2000, 2010]], labels=[[0, 0, 1, 1, 2, 2], [0, 1, 0, 1, 0, 1]])
level属性表示索引的等级,每个数据都有多级的不同的标签
# 将pop数据的索引重置,可见层级索引
pop = pop.reindex(index)
pop
California 2000 33871648 2010 37253956 New York 2000 18976457 2010 19378102 Texas 2000 20851820 2010 25145561 dtype: int64
# 现在用切片的方式查询2010年的全部数据
pop[:, 2010]
California 37253956 New York 19378102 Texas 25145561 dtype: int64
pop['California'] # 不用 pop['California', :]
2000 33871648 2010 37253956 dtype: int64
高维数据的多级索引
二维多级索引的Series对象可以和DF对象相互转化,有专用的方法
# 二维Series转DF
pop_df = pop.unstack()
pop_df
2000 | 2010 | |
---|---|---|
California | 33871648 | 37253956 |
New York | 18976457 | 19378102 |
Texas | 20851820 | 25145561 |
# DF转二维Series
pop_df.stack()
California 2000 33871648 2010 37253956 New York 2000 18976457 2010 19378102 Texas 2000 20851820 2010 25145561 dtype: int64
通过添加数据,可以提升数据的维数,而这很轻松方便
# 添加18岁以下人口的数据
pop_df = pd.DataFrame({'total': pop,
'under18': [9267089, 9284094,
4687374, 4318033,
5906301, 6879014]})
pop_df
total | under18 | ||
---|---|---|---|
California | 2000 | 33871648 | 9267089 |
2010 | 37253956 | 9284094 | |
New York | 2000 | 18976457 | 4687374 |
2010 | 19378102 | 4318033 | |
Texas | 2000 | 20851820 | 5906301 |
2010 | 25145561 | 6879014 |
通用函数和其他功能也适用于多级索引
# 计算18岁以下人口占总人口的比例
f_u18 = pop_df['under18'] / pop_df['total']
f_u18.unstack()
2000 | 2010 | |
---|---|---|
California | 0.273594 | 0.249211 |
New York | 0.247010 | 0.222831</ |