文章目录
- 层次化索引的概念
- 层次化索引的创建
- 使用嵌套列表的方式构造层次化索引对象
- Series对象
- DataFrame对象
- 通过MultiIndex类的方法构建层次化索引
- 通过from_tuples()方法创建MultiIndex对象
- 通过from_arrays()方法创建MultiIndex对象
- 通过from_product()方法创建MultiIndex对象
- 层次化索引的操作
- 选取子集
- 获取外层索引子集
- 获取内层索引子集
- 交换分层顺序——swaplevel()
- 排序分层
- sort_index()
- sort_values()
层次化索引的概念
只有一层索引结构(行索引、列索引)的Pandas对象称为单层索引,层次化索引可以理解为单层索引的延申,即在一个轴方向上具有多层索引。
层次化索引的创建
使用嵌套列表的方式构造层次化索引对象
Series对象
使用构造方法创造Series对象时,index参数接收了一个嵌套列表来设置索引的层级。
嵌套的第一个列表会作为外层索引,第二个列表会作为内层索引。
import pandas as pd
import numpy as npse = pd.Series([1, 2, 3, 4, 5, 6, 7, 8],index=[['河北省', '河北省', '河北省', '河北省','河南省', '河南省', '河南省', '河南省'],['石家庄', '唐山', '邯郸', '秦皇岛', '郑州', '开封', '洛阳', '新乡']])
print(se)
输出结果:
河北省 石家庄 1唐山 2邯郸 3秦皇岛 4
河南省 郑州 5开封 6洛阳 7新乡 8
dtype: int64
DataFrame对象
嵌套函数中两个列表的长度必须是保持一致的,否则将会出现ValueError错误。
df = DataFrame([1, 2, 3, 4, 5, 6, 7, 8],index=[['河北省', '河北省', '河北省', '河北省','河南省', '河南省', '河南省', '河南省'],['石家庄', '唐山', '邯郸', '秦皇岛', '郑州', '开封', '洛阳', '新乡']],columns=['占地面积'])
print(df)
df1 = DataFrame({'占地面积': [1, 2, 3, 4, 5, 6, 7, 8]},index=[['河北省', '河北省', '河北省', '河北省','河南省', '河南省', '河南省', '河南省'],['石家庄', '唐山', '邯郸', '秦皇岛', '郑州', '开封', '洛阳', '新乡']])
print(df1)
输出结果: 两种方式的输出结果是一致的
占地面积
河北省 石家庄 1唐山 2邯郸 3秦皇岛 4
河南省 郑州 5开封 6洛阳 7新乡 8占地面积
河北省 石家庄 1唐山 2邯郸 3秦皇岛 4
河南省 郑州 5开封 6洛阳 7新乡 8
通过MultiIndex类的方法构建层次化索引
除了使用嵌套列表的方式构造层次化索引以外,还可以通过MultiIndex类的方法构建一个层次化索引。
MultiIndex类提供了3种创建层次化索引的方法。
MultiIndex.from_tuples():将元组列表转换为MultiIndex。
MultiIndex.from_arrays():将数组列表转换为MultiIndex。
MultiIndex.from_product():从多个集合的笛卡尔乘积种创建一个MultiIndex。
MultiIndex类对象种有三个比较重要的属性
levels : 表示每个级别的唯一标签
labels : 表示每一个索引列种每个元素在levels中对应的第几个元素
names :设置索引等级名称
通过from_tuples()方法创建MultiIndex对象
from_tuples()方法可以将包含若干个元组的列表转换为MultiIndex对象,其中元组的第一个元素作为外层索引,元组的第二个元素作为内层索引。
from pandas import MultiIndexlist_tuples = [('A', 'A1'), ('A', 'A2'), ('A', 'A3'), ('B', 'B1'), ('B', 'B2')]
# 创建包含多个元组的列表
multi_tuple = MultiIndex.from_tuples(tuples=list_tuples, names=['外层索引', '内层索引'])
# 根据元组列表创建一个MultiIndex对象
print(multi_tuple)
输出结果:
MultiIndex([('A', 'A1'),('A', 'A2'),('A', 'A3'),('B', 'B1'),('B', 'B2')],names=['外层索引', '内层索引'])
接下来,创建一个DataFrame对象,把刚创建的创建的multi_tuple传递给index参数。
import pandas as pdvalue = [[1, 2, 3], [8, 5, 7], [4, 7, 7], [5, 5, 4], [4, 9, 9]]
df_tuple = pd.DataFrame(data=value, index=multi_tuple)
print(df_tuple)
输出结果:
外层索引 内层索引
A A1 1 2 3A2 8 5 7A3 4 7 7
B B1 5 5 4B2 4 9 9
通过from_arrays()方法创建MultiIndex对象
from_arrays()方法是将数组列表转换为MultiIndex对象,其中嵌套的第一个列表将作为外层索引,嵌套的第二个列表将作为内层索引。
from pandas import MultiIndexmulti_array = MultiIndex.from_arrays(arrays=[['A', 'B', 'A', 'B', 'B'],['A1', 'A2', 'B1', 'B2', 'B3']],names=['外层索引', '内层索引'])
# 根据列表创建一个MultiIndex对象
print(multi_array)
输出结果:
MultiIndex([('A', 'A1'),('B', 'A2'),('A', 'B1'),('B', 'B2'),('B', 'B3')],names=['外层索引', '内层索引'])
参数arrays既可以接收列表,也可以接受数组,不过每个列表或者数组的长度必须是相同的。
接下来,创建一个DataFrame对象,把刚刚创建的multi_array传递给index参数。
import pandas as pd
import numpy as npvalue1 = np.arange(10).reshape(5, 2)
df_array = pd.DataFrame(data=value1, index=multi_array)
print(df_array)
输出结果:
0 1
外层索引 内层索引
A A1 0 1
B A2 2 3
A B1 4 5
B B2 6 7B3 8 9
通过from_product()方法创建MultiIndex对象
from_product()方法表示从多个集合的笛卡尔积中创建一个MultiIndex对象。
number = [0, 1, 2]
colors = ['green', 'purple']
multi_product = pd.MultiIndex.from_product(iterables=[number, colors],names=['number', 'color'])
print(multi_product)
输出结果:
MultiIndex([(0, 'green'),(0, 'purple'),(1, 'green'),(1, 'purple'),(2, 'green'),(2, 'purple')],names=['number', 'color'])
接下来,创建一个DataFrame对象,把刚刚创建的multi_product传递给index参数,让该对象有两层索引结构。
value2 = np.arange(12).reshape(6, 2)
df_product = pd.DataFrame(data=value2, index=multi_product)
print(df_product)
输出结果:
0 1
number color
0 green 0 1purple 2 3
1 green 4 5purple 6 7
2 green 8 9purple 10 11
层次化索引的操作
选取子集
创建Series对象
ser_obj = Series([50, 60, 40, 94, 63, 101, 200, 56, 45],index=[['小说', '小说', '小说','散文随笔', '散文随笔', '散文随笔','传记', '传记', '传记'],['高山上的小邮局', '失踪的总统', '绿毛水怪','皮囊', '浮生六记', '自在独行','梅西', '老舍自传', '库里传']])
print(ser_obj)
输出结果:
小说 高山上的小邮局 50失踪的总统 60绿毛水怪 40
散文随笔 皮囊 94浮生六记 63自在独行 101
传记 梅西 200老舍自传 56库里传 45
dtype: int64
获取外层索引子集
例如获取所有外层索引为“小说”的子集
print(ser_obj['小说'])
输出结果:
高山上的小邮局 50
失踪的总统 60
绿毛水怪 40
dtype: int64
获取内层索引子集
例如获取内层索引为“老舍自传”的子集
print(ser_obj[:, '老舍自传'])
输出结果:
传记 56
dtype: int64
交换分层顺序——swaplevel()
交换分层顺序是指交换外层索引和内层索引的位置。
print(ser_obj.swaplevel())
输出结果:
高山上的小邮局 小说 50
失踪的总统 小说 60
绿毛水怪 小说 40
皮囊 散文随笔 94
浮生六记 散文随笔 63
自在独行 散文随笔 101
梅西 传记 200
老舍自传 传记 56
库里传 传记 45
dtype: int64
排序分层
sort_index()
sort_index(
self,
axis=0,
level=None,
ascending=True,
inplace=False,
kind=“quicksort”,
na_position=“last”,
sort_remaining=True,
ignore_index: bool = False,
)
上述方法的部分参数含义如下:
ascending: 是否升序排列,默认为True,升序排列。
在使用sort_index()方法排序时,会优先选择按外层索引进行排序,然后再按照内层索引进行排序。
创建一个DataFrame对象
df_obj = DataFrame({'word': ['a', 'b', 'd', 'e', 'f', 'k', 'd', 's', 'l'],'num':['1', '2', '4', '5', '3', '2', '6', '2', '3']},index=[['A', 'A', 'A', 'C', 'C', 'C', 'B', 'B', 'B'],[1, 3, 2, 3, 1, 2, 4, 5, 8]])
print(df_obj)
输出结果:
word num
A 1 a 13 b 22 d 4
C 3 e 51 f 32 k 2
B 4 d 65 s 28 l 3
按索引排序
print(df_obj.sort_index())
输出结果:
word num
A 1 a 12 d 43 b 2
B 4 d 65 s 28 l 3
C 1 f 32 k 23 e 5
sort_values()
sort_values(
self,
by,
axis=0,
ascending=True,
inplace=False,
kind=“quicksort”,
na_position=“last”,
ignore_index=False,
)
上述方法的部分参数含义如下:
by: 按指定的值排序,是sort_values()必须填写的参数
按照列索引num进行降序排列
print(df_obj.sort_values(by=['num'], ascending=False))
输出结果:
word num
B 4 d 6
C 3 e 5
A 2 d 4
C 1 f 3
B 8 l 3
A 3 b 2
C 2 k 2
B 5 s 2
A 1 a 1