Pandas的MultiIndex多层索引使用说明
作者:Jalen data analysis
MultiIndex多层索引
MultiIndex,即具有多个层次的索引,有些类似于根据索引进行分组的形式。通过多层次索引,我们就可以使用高层次的索引,来操作整个索引组的数据。通过给索引分类分组,则可以操作组数据。
1.创建方式
1.1.第一种:多维数组
我们在创建Series或DataFrame时,可以通过给index(columns)参数传递多维数组,进而构建多维索引。
【数组中每个维度对应位置的元素,组成每个索引值】
多维索引也可以设置名称(name性),属性的值为一维数组,元素的个数需要与索引的层数相同(每层索引都需要具有一个名称)。
1.2.第二种:MultiIndex
我们可以通过MultiIndex类的相关方法,预先创建一个MultiIndex对象,然后作为Series与DataFrame中的index(或columns)参数值。同时,可以通过names参数指定多层索引的名称。
from_arrays
:接收一个多维数组参数,高维指定高层索引,低维指定底层索引。from_tuples
:接收一个元组的列表,每个元组指定每个索引(高维索引,低维索引)。from_product
:接收一个可迭代对象的列表,根据多个可迭代对象元素的笛卡尔积进行创建索引。
from_product相对于前两个方法而言,实现相对简单,但是,也存在局限。
1.3.创建案例:
import numpy as np import pandas as pd import warnings warnings.filterwarnings('ignore')
#通过给index(columns)参数传递多维数组,进而构建多维索引 # 多层索引,指定一个多维数组。多维数组中,逐级给出每层索引的值。 s = pd.Series([1, 2, 3, 4], index=[["A", "A", "B", "B"], ["a", "b", "c", "d"]]) # 多于多层索引,每一层都具有一个名字。 s.index.names = ["index1", "index2"] display(s) display(s.loc["A"].loc["a"])
df=pd.DataFrame(np.arange(9).reshape(3, 3), columns=[["X", "X", "Y"], ["x1", 'x2', 'y1']],index=[["A", "B", "B"], ["a", 'a', 'b']]) display(df) display(df.loc["B"]) display(df["X"]) display(df.loc["B"].loc["a"]["X"]["x1"])
#通过MultiIndex类的方法进行创建。 # 通过列表的方式进行创建。(每个内嵌列表元素指定层次的索引,[[第0层索引], [第1层索引],……[第n层索引]]) array1=pd.MultiIndex.from_arrays([["A","A","B"],["a","b","a"]]) df=pd.DataFrame(np.random.rand(3,3),index=array1) display(df) # 通过元组构成列表的方式进行创建。[(高层,底层), (高层, 底层), ……] tuple1 = pd.MultiIndex.from_tuples([("A", "a"), ("A", "b"), ("B", "a")]) df2 = pd.DataFrame(np.random.random((3, 3)), index=tuple1) display(df2) # 通过乘积(笛卡尔积)的方式进行创建。 product1 = pd.MultiIndex.from_product([["A", "B"], ["a", "b"]]) df3 = pd.DataFrame(np.random.random((4, 3)), index=product1) display(df3)
2.多层索引操作
对于多层索引,同样也支持单层索引的相关操作,例如,索引元素,切片,索引数组选择元素等。我们也可以根据多级索引,按层次逐级选择元素。
多层索引的优势:通过创建多层索引,我们就可以使用高层次的索引,来操作整个索引组的数据。格式:
- s[操作]
- s.loc[操作]
- s.iloc[操作]
其中,操作可以是索引,切片,数组索引,布尔索引。
2.1.Series多层索引
- 通过loc(标签索引)操作,可以通过多层索引,获取该索引所对应的一组值。
- 通过iloc(位置索引)操作,会获取对应位置的元素值(与是否多层索引无关)。
- 通过s[操作]的行为有些诡异,建议不用。
- 对于索引(单级),首先按照标签选择,如果标签不存在,则按照位置选择。
- 对于多级索引,则按照标签进行选择。
- 对于切片,如果提供的是整数,则按照位置选择,否则按照标签选择。
- 对于数组索引, 如果数组元素都是整数,则根据位置进行索引,否则,根据标签进行索引。
2.2.DataFrame多层索引
- 通过loc(标签索引)操作,可以通过多层索引,获取该索引所对应的一组值。
- 通过iloc(位置索引)操作,会获取对应位置的一行(与是否多层索引无关)。
- 通过s[操作]的行为有些诡异,建议不用。
- 对于索引,根据标签获取相应的列(如果是多层索引,则可以获得多列)。
- 对于数组索引, 根据标签,获取相应的列(如果是多层索引,则可以获得多列)。
- 对于切片,首先按照标签进行索引,然后再按照位置进行索引(取行)。
2.3.交换索引
df.swaplevel(i=-2, j=-1, axis=0)
我们可以调用DataFrame对象的swaplevel方法来交换两个层级索引。该方法默认对倒数第2层与倒数第1层进行交换。我们也可以指定交换的层。层次从0开始,由外向内递增(或者由上到下递增),也可以指定负值,负值表示倒数第n层。除此之外,我们也可以使用层次索引的名称来进行交换。
df = pd.DataFrame(np.random.rand(4, 4), index=[["A", "A", "B", "B"], ["a1", "a1", "b1", "c1"], ["a2", "b2", "c2", "c2"]]) df.index.names = ["layer1", "layer2", "layer3"] display(df) # 多层索引,编号从外向内,0, 1, 2, 3.同时,索引编号也支持负值。 # 负值表示从内向外,-1, -2, -3. -1表示最内层。 display(df.swaplevel()) #默认对倒数第2层与倒数第1层进行交换 display(df.swaplevel(0, 2)) # 交换多层索引时,我们除了可以指定层次的编号外,也可以指定索引层次的名称。 display(df.swaplevel("layer1", "layer3"))
2.4.索引排序
我们可以使用sort_index方法对索引进行排序处理。
Signature: df.sort_index(axis=0, level=None, ascending=True, inplace=False, kind='quicksort', na_position='last', sort_remaining=True, by=None)
level
:指定根据哪一层进行排序,默认为最外(上)层。该值可以是数值,索引名,或者是由二者构成的列表。inplace
:是否就地修改。默认为False。
display(df.sort_index()) #默认索引排序 # 自定义排序的层次。 display(df.sort_index(level=1)) display(df.sort_index(level=2)) # 也可以通过索引的名称进行排序。 display(df.sort_index(level="layer1")) display(df.sort_index(level="layer2"))
2.5.索引堆叠
通过DataFrame对象的stack方法,可以进行索引堆叠,即将指定层级的列转换成行。
level
:指定转换的层级,默认为-1。
# 进行堆叠 列->行 取消堆叠 行->列 df.stack() df.unstack()
2.6.取消堆叠
通过DataFrame对象的unstack方法,可以取消索引堆叠,即将指定层级的行转换成列。 level:指定转换的层级,默认为-1。 fill_value:指定填充值。默认为NaN。
df = pd.DataFrame(np.random.rand(4, 4), index=[["A", "B", "B", "A"], ["b", "b", "a", "c"], ["b2", "c2", "a2", "c2"]]) df.index.names = ["layer1", "layer2", "layer3"] display(df)
# 取消堆叠,如果没有匹配的数据,则显示空值NaN。 display(df.unstack())
# 我们可以指定值去填充NaN(空值)。 df.unstack(fill_value=11)
# unstack默认会将最内层取消堆叠,我们也可以自行来指定层次。 display(df.unstack(0))
# 进行堆叠 列->行 取消堆叠 行->列 df.stack() # df.unstack() # stack堆叠也可以指定层次。 # stack堆叠也可以通过索引名进行操作。 df.stack(0)
2.7.设置索引
在DataFrame中,如果我们需要将现有的某一(几)列作为索引列,可以调用set_index方法来实现。
Signature
: df.set_index(keys, drop=True, append=False, inplace=False, verify_integrity=False)drop
:是否丢弃作为新索引的列,默认为True。append
:是否以追加的方式设置索引,默认为False。inplace
:是否就地修改,默认为False。
df = pd.DataFrame({"pk":[1, 2, 3, 4], "age":[15, 20, 17, 8], "name":["n1", "n2", "n3", "n4"]}) display(df) df1 = df.set_index("pk", drop=False) display(df1)
2.8.重置索引
调用在DataFrame对象的reset_index,可以重置索引。该操作与set_index正好相反。
Signature
: df.reset_index(level=None, drop=False, inplace=False, col_level=0, col_fill='')level
:重置索引的层级,默认重置所有层级的索引。如果重置所有索引,将会创建默认整数序列索引。drop
:是否丢弃重置的索引列,默认为False。inplace
:是否就地修改,默认为False。
df = pd.DataFrame({"pk":[1, 2, 3, 4], "age":[15, 20, 17, 8], "name":["n1", "n2", "n3", "n4"]}) #display(df) df1 = df.set_index("pk", drop=False) #display(df1) df2 = df1.reset_index(0, drop=True) display(df2)
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。