如果我们可以用含多级 索引的一维 Series 数据表示二维数据,那么我们就可以用 Series 或 DataFrame 表示三维 甚至更高维度的数据。多级索引每增加一级,就表示数据增加一维,利用这一特点就可以 轻松表示任意维度的数据了
一、创建一个多层索引的series
普通方法通过元组构成Series的多级索引
index= [('深圳', 2000), ('深圳', 2010), ('上海', 2000), ('上海', 2010), ('广东', 2000), ('广东', 2010)] populations= [33871648, 37253956, 18976457, 19378102, 20851820, 25145561] pop= pd.Series(populations, index=index) pop
代码结果:
(深圳, 2000) 33871648 (深圳, 2010) 37253956 (上海, 2000) 18976457 (上海, 2010) 19378102 (广东, 2000) 20851820 (广东, 2010) 25145561 dtype: int64
通过MultiIndex方法通过元组构成的多级索引
index= pd.MultiIndex.from_tuples(index) index
代码结果:
MultiIndex(levels=[['上海', '广东', '深圳'], [2000, 2010]], labels=[[2, 2, 0, 0, 1, 1], [0, 1, 0, 1, 0, 1]])
unstack() 方法可以快速将一个多级索引的 Series 转化为普通索引的 DataFrame
pop_df= pop.unstack() pop_df
?
stack() 方法实现相反的效果
pop_df.stack()
代码结果:
上海 2000 18976457 2010 19378102 广东 2000 20851820 2010 25145561 深圳 2000 33871648 2010 37253956 dtype: int64
二、多级索引的创建方法
Series 或 DataFrame 创建多级索引最直接的办法就是将 index 参数设置为至少二维的索
引数组.
df= pd.DataFrame(np.random.rand(4, 2), index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]], columns=['data1', 'data2']) df
?
将元组作为键的字典传递给 Pandas,Pandas 也会默认转换为 MultiIndex
data= {('深圳', 2000): 33871648, ('深圳', 2010): 37253956, ('广东', 2000): 20851820, ('广东', 2010): 25145561, ('上海', 2000): 18976457, ('上海', 2010): 19378102} pd.Series(data)
代码结果:
深圳 2000 33871648 2010 37253956 广东 2000 20851820 2010 25145561 上海 2000 18976457 2010 19378102 dtype: int64
显式地创建多级索引
pd.MultiIndex中的类方法更加灵活地构建多级索引。
pd.MultiIndex.from_arrays([['a', 'a', 'b', 'b'], [1, 2, 1, 2]])
代码结果:
MultiIndex(levels=[['a', 'b'], [1, 2]], labels=[[0, 0, 1, 1], [0, 1, 0, 1]])
通过包含多个索引值的元组构成的列表创建 MultiIndex
pd.MultiIndex.from_tuples([('a', 1), ('a', 2), ('b', 1), ('b', 2)])
代码结果:
MultiIndex(levels=[['a', 'b'], [1, 2]], labels=[[0, 0, 1, 1], [0, 1, 0, 1]])
用两个索引的笛卡尔积(Cartesianproduct)创建MultiIndex
pd.MultiIndex.from_product([['a', 'b'], [1, 2]])
代码结果:
MultiIndex(levels=[['a', 'b'], [1, 2]], labels=[[0, 0, 1, 1], [0, 1, 0, 1]])
直接用levels(包含每个等级的索引值列表的列表)和 labels(包含每个索引值 标签列表的列表)创建 MultiIndex
pd.MultiIndex(levels=[['a', 'b'], [1, 2]], labels=[[0, 0, 1, 1], [0, 1, 0, 1]]) MultiIndex(levels=[['a', 'b'], [1, 2]], labels=[[0, 0, 1, 1], [0, 1, 0, 1]])
多级索引的等级名称
给 MultiIndex 的等级加上名称会为一些操作提供便利。你可以在前面任何一个 MultiIndex
构造器中通过 names 参数设置等级名称,也可以在创建之后通过索引的 names 属性来修改 名称:
pop.index.names= ['state', 'year'] pop
代码结果:
state year 深圳 2000 33871648 2010 37253956 上海 2000 18976457 2010 19378102 广东 2000 20851820 2010 25145561 dtype: int64
多级列索引
每个 DataFrame 的行与列都是对称的,也就是说既然有多级行索引,那么同样可以有多级 列索引
# 多级行列索引 index= pd.MultiIndex.from_product([[2013, 2014], [1, 2]], names=['year', 'visit']) columns= pd.MultiIndex.from_product([['Bob', 'Guido', '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 ?
?
代码结果:?
上面创建了一个简易的四维数据,四个维度分别为被检查 人的姓名、检查项目、检查年份和检查次数。可以在列索引的第一级查询姓名,从而获取 包含一个人(例如 Guido)全部检查信息的 DataFrame:
health_data['Guido']
?代码结果:
?
三、多级索引的取值与切片
对 MultiIndex 的取值和切片操作很直观,你可以直接把索引看成额外增加的维度。我们先
来介绍 Series 多级索引的取值与切片方法。
Series多级索引
pop
代码结果:
state year 深圳 2000 33871648 2010 37253956 上海 2000 18976457 2010 19378102 广东 2000 20851820 2010 25145561 dtype: int64
通过对多个级别索引值获取单个元素
pop['深圳', 2000]
代码结果:
33871648
局部取值(partialindexing),即只取索引的某一个层级
pop['深圳']
代码结果:
year 2000 33871648 2010 37253956 dtype: int64
通过布尔掩码选择数据
pop[pop>22000000]
代码结果:
state year 深圳 2000 33871648 2010 37253956 广东 2010 25145561 dtype: int64
用花哨的索引选择数据:
pop[['深圳', '上海']]
代码结果:
state year 深圳 2000 33871648 2010 37253956 上海 2000 18976457 2010 19378102 dtype: int64
DataFrame多级索引
health_data['Guido', 'HR']
代码结果:
year visit 2013 1 41.0 2 12.0 2014 1 34.0 2 34.0 Name: (Guido, HR), dtype: float64
loc、iloc和ix索引器的使用
health_data.iloc[:2, :2]
?代码结果:
用 Python 内置的 slice() 函数获取切片,但是还有一种更好的办法,就是使用 IndexSlice对象。
idx= pd.IndexSlice health_data.loc[idx[:, 1], idx[:, 'HR']]
?
关注领资料:
1.如果觉得还可以,记得点击右上角的关注,随手点个转发让更多人看到哦。
2.如果你对Python感兴趣,我为你准备了一些Python教程,私信「python」领取。
3.如果对数据分析感兴趣我这里有一本《利用python进行数据分析》私信「书籍」就可以得到。