Python Pandas – 从DataFrame创建多级索引
在处理复杂的数据集时,多级索引是一种非常有用的方法,它可以帮助我们更好地组织和查询数据。在Pandas中,我们可以从DataFrame创建多级索引,本文将介绍如何进行操作。
简单的例子
我们从一个简单的DataFrame开始,包含了销售部门不同经理的销售额数据:
import pandas as pd
df = pd.DataFrame({'部门': ['销售部', '销售部', '销售部', '市场部', '市场部', '研发部'],
'经理': ['张三', '李四', '王五', '赵六', '孙七', '周八'],
'销售额': [100, 200, 300, 400, 500, 600]})
print(df)
输出如下:
部门 经理 销售额
0 销售部 张三 100
1 销售部 李四 200
2 销售部 王五 300
3 市场部 赵六 400
4 市场部 孙七 500
5 研发部 周八 600
我们希望能够按照“部门”和“经理”两个因素对销售数据进行分组和查询。
首先,我们可以使用set_index
方法将“部门”和“经理”这两列作为索引,如下所示:
df_indexed = df.set_index(['部门', '经理'])
print(df_indexed)
输出:
销售额
部门 经理
销售部 张三 100
李四 200
王五 300
市场部 赵六 400
孙七 500
研发部 周八 600
我们可以看到现在的DataFrame已经成为了一个两级索引,其中“部门”作为第一层索引,“经理”作为第二层索引。
接下来,我们可以根据这两个索引进行查询。例如,如果我们想查询“销售部”的所有数据,可以使用loc
方法,如下所示:
df_sales = df_indexed.loc['销售部']
print(df_sales)
输出如下:
销售额
经理
张三 100
李四 200
王五 300
同样,如果我们想查询“张三”的销售数据,也可以使用loc
方法,如下所示:
sales_zhangsan = df_indexed.loc[('销售部', '张三')]
print(sales_zhangsan)
输出:
销售额 100
Name: (销售部, 张三), dtype: int64
多级索引的创建和应用
上面的例子中,我们通过set_index
方法将DataFrame的行索引设置成了多级索引。除此之外,我们还可以在创建DataFrame的时候直接指定多级索引。
例如,我们可以通过创建一个元素为元组的列表来指定多级索引。以下是一个例子:
data = [((1, 'A'), 10), ((1, 'B'), 20), ((2, 'A'), 30), ((2, 'B'), 40)]
multi_index = pd.MultiIndex.from_tuples(data, names=['first', 'second'])
df_multi = pd.DataFrame({'values': [10, 20, 30, 40]}, index=multi_index)
print(df_multi)
输出:
values
first second
1 A 10
B 20
2 A 30
B 40
我们可以看到,这个DataFrame有两个级别的行索引,“first”和“second”。我们可以使用loc
方法来查询数据,例如查看“first”为1的所有数据:
df_first = df_multi.loc[(1,)]
print(df_first)
输出:
values
second
A 10
B 20
上面的代码中,我们使用了(1,)
来选取“first”为1的所有数据,“:`表示选取所有的“second”。
另外,有时我们会想要对多级索引的级别进行排序。Pandas提供了sort_index
方法来实现这一点。例如,我们可以按照“second”级别的值进行排序:
df_sorted = df_multi.sort_index(level='second')
print(df_sorted)
输出:
values
first second
1 A 10
2 A 30
1 B 20
2 B 40
上面的代码中,我们使用sort_index
方法并设置level='second'
来按照“second”级别的值进行排序。
重塑和堆叠
有时候,我们可能需要将多级索引的某些级别转换为列,或者将某些列转换为行,这时可以使用stack
和unstack
方法来实现。
其中,stack
方法可以将DataFrame的列转换为行,同时将转换后的行索引变成多级索引的一级;而unstack
方法则可以将行索引中的某一级转换为列,同时将转换后的列索引变成多级索引的一级。
以下是一个例子,我们将上面的例子中的“first”级别的行索引转换为列:
df_stacked = df_multi.reset_index().rename(columns={'level_0': 'first', 'level_1': 'second'}).set_index(['second', 'first']).stack().reset_index().rename(columns={0: 'values'})
print(df_stacked)
输出:
second first level_2 values
0 A 1 values 10
1 A 2 values 30
2 B 1 values 20
3 B 2 values 40
可以看到,我们首先使用reset_index
方法将多级索引变成列,然后使用set_index
方法将“second”和“first”两列变回行索引。接下来,我们使用stack
方法将“first”这一行索引级别的列转换为行。最后,我们使用rename
方法来命名转换后的列,输出结果与原始数据结构并不相同。
如果我们想将上面的结果再转换回去,也可以使用unstack
方法,如下所示:
df_unstacked = df_stacked.set_index(['second', 'first', 'level_2']).unstack('first')
print(df_unstacked)
输出:
values
first 1 2
second
A 10 30
B 20 40
上面的代码中,我们首先使用set_index
方法将行索引设置为多级索引,然后使用unstack
方法将“first”这一级别的索引转换为列。