Python Pandas – 将MultiIndex的级别作为列创建DataFrame,但避免设置返回的DataFrame的索引
随着数据量的不断增长,我们在数据处理时需要面对越来越复杂的数据结构。其中,MultiIndex是一个用于处理多维数据的非常实用的工具。然而,MultiIndex有时会给数据的展示和处理带来一些不便。本文将介绍如何将MultiIndex的级别作为列创建DataFrame,但又避免将MultiIndex设置成DataFrame的索引。
什么是MultiIndex
MultiIndex是一种索引方式,它允许在一个轴上拥有多个级别的标签。在Pandas中,我们可以使用MultiIndex来表示多维数据的行和列索引,这样就可以在同一个表格中保存非常复杂的数据。
假设我们有以下数据集合:
import pandas as pd
import numpy as np
tuples = [('bar', 'one'), ('bar', 'two'),
('baz', 'one'), ('baz', 'two'),
('foo', 'one'), ('foo', 'two'), ('foo', 'two')]
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
values = np.random.randn(7)
df = pd.DataFrame({'A': values, 'B': values+1}, index=index)
这里我们定义了一个MultiIndex为(first, second),它表示三个key:’bar’、’baz’和’foo’,和三个value:’one’、’two’和’two’。同时,我们利用NumPy随机生成了两列数据’A’和’B’,并使用MultiIndex作为Dataframe的行索引。
df
A B
first second
bar one -0.982865 -0.982865
two -0.982865 -0.982865
baz one -1.188479 -1.188479
two 0.343659 0.343659
foo one -1.181684 -1.181684
two 1.719280 1.719280
two -0.105384 -0.105384
可以看出,MultiIndex既提供了多维度的数据,也会使得数据集变得比较复杂。接下来,我们将介绍如何将MultiIndex的级别作为列创建DataFrame,同时又避免将MultiIndex设置成DataFrame的索引。
如何将MultiIndex的级别作为列创建DataFrame
当我们使用MultiIndex数据集时,有时我们需要将其中某些维度作为列来展示,这样有利于提升数据的可读性。下面我们将介绍如何将MultiIndex的级别作为列创建DataFrame。
df.reset_index(level='second', inplace=True)
这里我们使用了DataFrame的reset_index函数来撤销MultiIndex的索引级别,并将第二级别的数据作为一个新的列添加到DataFrame中。其中,level参数指定需要重置的索引级别,inplace=True则表示将更改应用于原始数据集。
df
first second A B
0 bar one -0.982865 -0.982865
1 bar two -0.982865 -0.982865
2 baz one -1.188479 -1.188479
3 baz two 0.343659 0.343659
4 foo one -1.181684 -1.181684
5 foo two 1.719280 1.719280
6 foo two -0.105384 -0.105384
可以看出,现在我们将MultiIndex的第二级别作为新的列加入到了数据中,但MultiIndex本身并未作为一个新的列添加到数据中。下面我们将介绍如何将MultiIndex的第一级别作为新的列加入到数据中。
df.reset_index(level='first', inplace=True)
这里我们再次使用了reset_index函数,但这次我们将MultiIndex的第一级别作为一个新的列添加到DataFrame中。同样,level参数指定需要重置的索引级别,inplace=True表示将更改应用于原始数据集。现在我们可以看到,我们成功将MultiIndex的第一级别作为新的列加入到数据中:
df
second first A B
0 one bar -0.982865 -0.982865
1 two bar -0.982865 -0.982865
2 one baz -1.188479 -1.188479
3 two baz 0.343659 0.343659
4 one foo -1.181684 -1.181684
5 two foo 1.719280 1.719280
6 two foo -0.105384 -0.105384
如何避免将MultiIndex设置成DataFrame的索引
上面的例子中,我们是先将MultiIndex的一级和二级索引分别作为新的列添加到Dataframe中。这种方法的好处是可以将MultiIndex展示成DataFrame中的一部分,但坏处是MultiIndex会被转换成了DataFrame中的一般列。如果我们需要进行一些只能通过MultiIndex进行的计算或聚合操作,那么这种方法可能会让我们失去这些功能。因此,如果我们只是为了更好的展示数据,那么上述方法或许是可行的;但是如果我们还需要继续使用MultiIndex,则需要避免这种方法。
那么有没有不使用reset_index函数的方法呢?当然有。我们可以使用pd.DataFrame.from_records()方法来构建DataFrame。下面是示例代码:
df_cols = pd.DataFrame.from_records(df.index.tolist())
df_data = pd.DataFrame(df.values, columns=['A', 'B'])
df = pd.concat([df_cols, df_data], axis=1)
这个方法将MultiIndex重塑为两个DataFrame,一个包含列名,一个包含数据。然后,我们使用pd.concat()方法将这两个DataFrame组合成一个新的DataFrame。
df
first second A B
0 bar one -0.982865 -0.982865
1 bar two -0.982865 -0.982865
2 baz one -1.188479 -1.188479
3 baz two 0.343659 0.343659
4 foo one -1.181684 -1.181684
5 foo two 1.719280 1.719280
6 foo two -0.105384 -0.105384
可以看到,现在MultiIndex没有被设置为DataFrame的索引。可以使用df.set_index()方法将任何列设置为索引,如下所示:
df.set_index(['first', 'second'])
A B
first second
bar one -0.982865 -0.982865
two -0.982865 -0.982865
baz one -1.188479 -1.188479
two 0.343659 0.343659
foo one -1.181684 -1.181684
two 1.719280 1.719280
two -0.105384 -0.105384
我们现在可以继续使用MultiIndex进行计算和聚合操作,而不需要受到任何约束。
结论
在处理MultiIndex数据时,有时需要将其作为列展示。使用reset_index()方法可以将MultiIndex中的任意一维度作为新的列添加到DataFrame中。但若我们需要继续使用MultiIndex,则可以使用pd.DataFrame.from_records()方法将MultiIndex重塑为单独的DataFrame,并使用pd.concat()方法将其组合为一个新的DataFrame。这样做将保留MultiIndex的计算和聚合操作特性。因此,具体方法需根据数据处理的需求而定。
在使用这些方法时,我们需要注意重复列名的问题。在上面的示例代码中,由于我们重塑MultiIndex为两个DataFrame,因此需要为数据DataFrame设置列名。如果数据中有多个列名相同,并且在组合时需要针对此类重复列名进行操作,则需要在设置列名时特别注意。
总之,将MultiIndex的某些级别作为列展示可以提升数据的可读性,但需要注意需要继续使用MultiIndex时避免将其设置为DataFrame的索引。
极客笔记