Python Pandas 多重索引:MultiIndex 创建与应用指南

Python Pandas 多重索引:MultiIndex 创建与应用指南

本文介绍了如何在 Pandas 中创建和使用多重索引(MultiIndex)对象,包括通过MultiIndex.from_tuplesMultiIndex.from_productMultiIndex.from_frame等方法生成多重索引,并将其应用于SeriesDataFrame中。通过实例讲解了如何灵活访问和操作具有层次结构的数据,提高数据处理和分析的效率。

导入第三方库

import pandas as pd

一 创建 Series 多重索引对象

多重索引(MultiIndex)是 Pandas 中的一个功能,它允许你在数据结构(如 DataFrameSeries)中使用多个索引级别进行索引和访问数据。与传统的单级索引相比,多重索引可以让你更灵活地表示和操作具有层次结构的数据。

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"] 表示给多重索引中的两个级别命名,分别为 gradeclass
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   小勉

六 源码地址

代码地址:

国内看 Giteepandas/多索引数据.py

国外看 GitHubpandas/多索引数据.py

引用 莫烦 Python

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲代码不忘补水

感谢有你,让我的创作更有价值!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值