Python Pandas 多重索引:MultiIndex 创建与应用指南
本文介绍了如何在 Pandas 中创建和使用多重索引(MultiIndex)对象,包括通过MultiIndex.from_tuples
、MultiIndex.from_product
和MultiIndex.from_frame
等方法生成多重索引,并将其应用于Series
和DataFrame
中。通过实例讲解了如何灵活访问和操作具有层次结构的数据,提高数据处理和分析的效率。
文章目录
导入第三方库
import pandas as pd
一 创建 Series 多重索引对象
多重索引(MultiIndex
)是 Pandas
中的一个功能,它允许你在数据结构(如 DataFrame
或 Series
)中使用多个索引级别进行索引和访问数据。与传统的单级索引相比,多重索引可以让你更灵活地表示和操作具有层次结构的数据。
1 使用 MultiIndex.from_tuples
创建多重索引
1) 创建一个简单的 Series
对象
s = pd.Series(
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
], name="name")
print(s)
2) 创建一个多重索引的元组列表
tuples = [
# 年级,班级
("one", "1"),
("one", "1"),
("one", "2"),
("one", "2"),
("two", "1"),
("two", "1"),
("two", "2"),
("two", "2"),
]
tuples
是一个包含元组的列表,每个元组都表示年级和班级的组合。
3) 使用 MultiIndex.from_tuples
创建多重索引
index = pd.MultiIndex.from_tuples(
tuples, names=["grade", "class"])
print(index)
pd.MultiIndex.from_tuples(tuples, names=["grade", "class"])
用来创建一个多重索引(MultiIndex
),每个元组的第一个元素是年级,第二个元素是班级。names=["grade", "class"]
表示给多重索引中的两个级别命名,分别为grade
和class
。
4) 将多重索引应用到 Series
s = pd.Series(
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
], name="name", index=index)
print(s)
此示例为 Series
指定了一个多重索引 index=index
,该索引包含了年级和班级的组合。运行结果:
grade class
one 1 小米
1 小明
2 小命
2 小勉
two 1 小牛
1 小鸟
2 小南
2 小妮
Name: name, dtype: object
可以使用 s.index
获取当前多重索引信息。
2 使用pd.MultiIndex.from_product
创建多重索引
1) 使用 pd.MultiIndex.from_product
创建多重索引
iterables = [
["one", "two"], # 年级
["1", "1", "2", "2"] # 每个学生所在班级
]
index2 = pd.MultiIndex.from_product(
iterables, names=["grade", "class"])
print(index2)
代码释义:
iterables
是一个包含两个列表的列表(二维):- 第一个列表
["one", "two"]
表示年级,包含两项:“one”和“two”。 - 第二个列表
["1", "1", "2", "2"]
表示班级,每个年级有两个班级(1班和2班)。
- 第一个列表
pd.MultiIndex.from_product(iterables, names=["grade", "class"])
通过计算笛卡尔积(product
),生成所有可能的组合,创建一个具有多重索引的MultiIndex
对象。names=["grade", "class"]
指定了索引级别的名称,分别为“年级”(grade
)和“班级”(class
)。
2) 创建 Series
并应用多重索引
s2 = pd.Series(
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
],
name="name",
index=index2)
运行结果
grade class
one 1 小米
1 小明
2 小命
2 小勉
two 1 小牛
1 小鸟
2 小南
2 小妮
Name: name, dtype: object
3 使用 pd.MultiIndex.from_frame
创建多重索引
1)创建一个普通的 DataFrame
df = pd.DataFrame(
[
# 年级,班级
("one", "1"),
("one", "1"),
("one", "2"),
("one", "2"),
("two", "1"),
("two", "1"),
("two", "2"),
("two", "2"),
],
columns=["grade", "class"]
)
2)使用 MultiIndex.from_frame
创建多重索引
index3 = pd.MultiIndex.from_frame(df)
print(index3)
pd.MultiIndex.from_frame(df)
通过将 DataFrame
中的列转换为多重索引,从而创建一个多重索引对象。df
的每一列将会作为多重索引的一个级别。
3)创建 Series
并应用多重索引
s3 = pd.Series(
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
],
name="name",
index=index3)
print(s3)
二 创建 DataFrame 多重索引对象
df1 = pd.DataFrame(
{"id": [11, 12, 13, 14, 15, 16, 17, 18],
"name":
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
]},
index=index)
print(df1)
运行结果
id name
grade class
one 1 11 小米
1 12 小明
2 13 小命
2 14 小勉
two 1 15 小牛
1 16 小鸟
2 17 小南
2 18 小妮
三 创建 Column 多重索引对象
df2 = pd.DataFrame(
[[11, 12, 13, 14, 15, 16, 17, 18],
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
]],
index=["id", "name"])
print(df2)
df2 = pd.DataFrame(
[[11, 12, 13, 14, 15, 16, 17, 18],
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
]],
index=["id", "name"],
columns=index, # 使用多重索引作为列索引
)
print(df2)
上例中将多重索引作为列索引应用到 DataFrame
,通过 columns=index
将多重索引作为列索引应用到 DataFrame
,使得每一列都包含年级和班级的信息。运行结果如下:
0 1 2 3 4 5 6 7
id 11 12 13 14 15 16 17 18
name 小米 小明 小命 小勉 小牛 小鸟 小南 小妮
grade one two
class 1 1 2 2 1 1 2 2
id 11 12 13 14 15 16 17 18
name 小米 小明 小命 小勉 小牛 小鸟 小南 小妮
四 获取多重索引中的数据
1 列索引获取数据
df3 = pd.DataFrame(
[[11, 12, 13, 14, 15, 16, 17, 18],
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
]],
index=["id", "name"],
columns=index, # 多索引加这
)
print(df3)
运行结果
grade one two
class 1 1 2 2 1 1 2 2
id 11 12 13 14 15 16 17 18
name 小米 小明 小命 小勉 小牛 小鸟 小南 小妮
获取数据
# 获取 "一年级"(grade = "one")的数据
# df3["one"] 返回包含 "一年级"(grade="one")所有班级数据的子DataFrame
print(df3["one"])
# 获取 "一年级 1 班"(grade = "one", class = "1")的数据
# df3["one"]["1"] 会首先获取 "一年级" 的数据,然后进一步获取班级为 "1" 的数据
print(df3["one"]["1"])
2 行索引获取数据
df4 = pd.DataFrame(
{"id": [11, 12, 13, 14, 15, 16, 17, 18],
"name":
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
]},
index=index)
print(df4)
运行结果
id name
grade class
one 1 11 小米
1 12 小明
2 13 小命
2 14 小勉
two 1 15 小牛
1 16 小鸟
2 17 小南
2 18 小妮
获取数据
# 使用 .loc 进行多重索引查询:获取 "一年级"(grade = "one")且班级为 "2"(class = "2")的学生数据
# df4.loc["one"] 获取 "一年级" 所有学生数据,.loc["2"] 进一步获取班级为 "2" 的数据
print(df4.loc["one"].loc["2"])
五 完整代码示例
# This is a sample Python script.
# Press ⌃R to execute it or replace it with your code.
# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings.
import pandas as pd
def print_hi(name):
# Use a breakpoint in the code line below to debug your script.
print(f'Hi, {name}') # Press ⌘F8 to toggle the breakpoint.
# 构建Row多索引
s = pd.Series(
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
], name="name")
print(s)
tuples = [
# 年级,班级
("one", "1"),
("one", "1"),
("one", "2"),
("one", "2"),
("two", "1"),
("two", "1"),
("two", "2"),
("two", "2"),
]
index = pd.MultiIndex.from_tuples(
tuples, names=["grade", "class"])
print(index)
s = pd.Series(
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
], name="name", index=index)
print(s)
print()
print(s.index)
iterables = [
["one", "two"], # 年级
["1", "1", "2", "2"] # 每个学生所在班级
]
index2 = pd.MultiIndex.from_product(
iterables, names=["grade", "class"])
print(index2)
s2 = pd.Series(
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
],
name="name",
index=index2)
print(s2)
df = pd.DataFrame(
[
# 年级,班级
("one", "1"),
("one", "1"),
("one", "2"),
("one", "2"),
("two", "1"),
("two", "1"),
("two", "2"),
("two", "2"),
],
columns=["grade", "class"]
)
index3 = pd.MultiIndex.from_frame(df)
print(index3)
s3 = pd.Series(
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
],
name="name",
index=index3)
print(s3)
# 构建DataFrame多索引
df1 = pd.DataFrame(
{"id": [11, 12, 13, 14, 15, 16, 17, 18],
"name":
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
]},
index=index)
print(df1)
# 构建Column多索引
df2 = pd.DataFrame(
[[11, 12, 13, 14, 15, 16, 17, 18],
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
]],
index=["id", "name"])
print(df2)
df2 = pd.DataFrame(
[[11, 12, 13, 14, 15, 16, 17, 18],
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
]],
index=["id", "name"],
columns=index, # 多索引加这
)
print(df2)
print()
# 选择数据
df3 = pd.DataFrame(
[[11, 12, 13, 14, 15, 16, 17, 18],
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
]],
index=["id", "name"],
columns=index, # 多索引加这
)
print(df3)
# 获取一年级数据
print(df3["one"])
# 获取一年级 1 班数据
print(df3["one"]["1"])
df4 = pd.DataFrame(
{"id": [11, 12, 13, 14, 15, 16, 17, 18],
"name":
["小米", "小明", # 一年一班
"小命", "小勉", # 一年二班
"小牛", "小鸟", # 二年一班
"小南", "小妮" # 二年二班
]},
index=index)
print(df4)
print(df4.loc["one"].loc["2"])
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
print_hi('多索引数据')
# See PyCharm help at https://www.jetbrains.com/help/pycharm/
复制粘贴并覆盖到你的 main.py 中运行,运行结果如下。
Hi, 多索引数据
0 小米
1 小明
2 小命
3 小勉
4 小牛
5 小鸟
6 小南
7 小妮
Name: name, dtype: object
MultiIndex([('one', '1'),
('one', '1'),
('one', '2'),
('one', '2'),
('two', '1'),
('two', '1'),
('two', '2'),
('two', '2')],
names=['grade', 'class'])
grade class
one 1 小米
1 小明
2 小命
2 小勉
two 1 小牛
1 小鸟
2 小南
2 小妮
Name: name, dtype: object
MultiIndex([('one', '1'),
('one', '1'),
('one', '2'),
('one', '2'),
('two', '1'),
('two', '1'),
('two', '2'),
('two', '2')],
names=['grade', 'class'])
MultiIndex([('one', '1'),
('one', '1'),
('one', '2'),
('one', '2'),
('two', '1'),
('two', '1'),
('two', '2'),
('two', '2')],
names=['grade', 'class'])
grade class
one 1 小米
1 小明
2 小命
2 小勉
two 1 小牛
1 小鸟
2 小南
2 小妮
Name: name, dtype: object
MultiIndex([('one', '1'),
('one', '1'),
('one', '2'),
('one', '2'),
('two', '1'),
('two', '1'),
('two', '2'),
('two', '2')],
names=['grade', 'class'])
grade class
one 1 小米
1 小明
2 小命
2 小勉
two 1 小牛
1 小鸟
2 小南
2 小妮
Name: name, dtype: object
id name
grade class
one 1 11 小米
1 12 小明
2 13 小命
2 14 小勉
two 1 15 小牛
1 16 小鸟
2 17 小南
2 18 小妮
0 1 2 3 4 5 6 7
id 11 12 13 14 15 16 17 18
name 小米 小明 小命 小勉 小牛 小鸟 小南 小妮
grade one two
class 1 1 2 2 1 1 2 2
id 11 12 13 14 15 16 17 18
name 小米 小明 小命 小勉 小牛 小鸟 小南 小妮
grade one two
class 1 1 2 2 1 1 2 2
id 11 12 13 14 15 16 17 18
name 小米 小明 小命 小勉 小牛 小鸟 小南 小妮
class 1 1 2 2
id 11 12 13 14
name 小米 小明 小命 小勉
class 1 1
id 11 12
name 小米 小明
id name
grade class
one 1 11 小米
1 12 小明
2 13 小命
2 14 小勉
two 1 15 小牛
1 16 小鸟
2 17 小南
2 18 小妮
id name
class
2 13 小命
2 14 小勉
六 源码地址
代码地址:
国内看 Gitee 之 pandas/多索引数据.py
国外看 GitHub 之 pandas/多索引数据.py
引用 莫烦 Python