查看全课大纲(第 53 / 101 节)
  1. 1.数据分析基本概念
  2. 2.学习数据分析的一般路线
  3. 3.数据分析的流程
  4. 4.数据类型
  5. 5.环境部署(1)
  6. 6.环境部署(2)
  7. 7.课程介绍
  8. 8.TXT文件操作
  9. 9.JSON文件操作
  10. 10.CSV文件操作
  11. 11.Excel文件操作
  12. 12.数据库及SQL常用语法
  13. 13.数据库基本操作
  14. 14.数据库多表连接
  15. 15.实战:欧洲职业足球数据库分析
  16. 16.爬虫简介
  17. 17.URL管理模块
  18. 18.网页下载模块
  19. 19.网页解析模块(1)
  20. 20.网页解析模块(2)
  21. 21.Scrapy简介
  22. 22.Scrapy使用步骤(1)
  23. 23.Scrapy使用步骤(2)
  24. 24.Scrapy使用步骤(3)
  25. 25.Scrapy使用步骤(4)
  26. 26.实战:获取国内城市空气质量指数数据
  27. 27.NumPy和SciPy介绍
  28. 28.多维数组
  29. 29.多维数组操作
  30. 30.NumPy的常用方法
  31. 31.向量化介绍
  32. 32.向量化及通用函数
  33. 33.实战:2016美国大选分析
  34. 34.数据结构-Series
  35. 35.数据结构-DataFrame
  36. 36.数据结构-Index
  37. 37.Series的索引操作
  38. 38.DataFrame的索引操作
  39. 39.索引操作总结
  40. 40.运算与对齐
  41. 41.函数应用操作(1) -- map
  42. 42.函数应用操作 (2) -- apply applymap
  43. 43.文件读写操作
  44. 44.排序操作
  45. 45.数据清洗--处理缺失数据
  46. 46.数据清洗--处理重复数据
  47. 47.数据清洗--替换数据
  48. 48.常用统计方法(1) -- describe quantile
  49. 49.常用统计方法(2) -- sum mean median count
  50. 50.常用统计方法(3) -- max min idxmax idxmin
  51. 51.常用统计方法(4) -- mad var std cumsum
  52. 52.实战:全球食品数据分析
  53. 53.层级索引
  54. 54.分组与聚合介绍
  55. 55.分组操作(1) -- GroupBy对象及常用聚合操作
  56. 56.分组操作(2) -- 自定义分组及聚合操作
  57. 57.透视表介绍
  58. 58.透视表操作
  59. 59.数据规整(1) -- 数据合并concat
  60. 60.数据规整(2) -- 数据连接merge
  61. 61.数据重构(3) -- 数据重构stack unstack
  62. 62.实战:互联网电影资料库分析
  63. 63.探索性数据分析EDA介绍
  64. 64.EDA的目的
  65. 65.EDA常用工具
  66. 66.Matplotlib绘图基本介绍
  67. 67.Matplotlib画布
  68. 68.散点图和柱状图的绘制
  69. 69.直方图的绘制
  70. 70.矩阵绘图
  71. 71.子图的使用
  72. 72.Matplotlib颜色、标记、线型
  73. 73.Matplotlib坐标刻度、标签、图例、标题
  74. 74.Seaborn介绍
  75. 75.数据集分布可视化(1) -- 单变量分布、双变量分布
  76. 76.数据集分布可视化(2) -- 变量关系可视化
  77. 77.类别数据可视化 -- 类别散布图、类别内数据分布、类别内统计图
  78. 78.交互式数据可视化工具Bokeh介绍
  79. 79.Bokeh绘制散点图、柱状图、盒子图、弦图
  80. 80.Bokeh绘制常用图形元素
  81. 81.3D绘图 -- mplot3d
  82. 82.3D曲线可视化
  83. 83.3D散点图可视化
  84. 84.3D柱状图可视化
  85. 85.Pandas绘图
  86. 86.实战:Lending Club借贷数据探索性分析及可视化
  87. 87.机器学习介绍及应用场景
  88. 88.机器学习建模介绍 (1) -- 分类
  89. 89.机器学习建模介绍 (2) -- 回归
  90. 90.机器学习建模介绍 (3) -- 聚类
  91. 91.机器学习分类
  92. 92.机器学习工具scikit-learn
  93. 93.使用scikit-learn的流程
  94. 94.数据集准备及划分
  95. 95.模型选择
  96. 96.数据预处理及特征工程
  97. 97.过拟合与欠拟合
  98. 98.模型调参介绍
  99. 99.模型调参方法
  100. 100.模型测试及评价
  101. 101.实战:通过移动设备行为数据预测性别和年龄

层级索引

约 9 分钟

📺 正在播放小象学院官方高清录播(支持倍速与清晰度调节)

小象实战讲义 · Python数据分析实战

在数据分析中,我们常常会遇到数据具有自然层次结构的情况,例如国家属于某个地区,产品属于某个类别。Pandas 提供的层级索引(MultiIndex)功能,可以让我们高效地组织和访问这类具有多级分组结构的数据。本节将学习如何设置、操作和使用层级索引,这是后续进行高级分组聚合和透视表分析的重要基础。

💡 核心导读

  • 什么是层级索引:理解 MultiIndex 对象的概念,它允许将多列组合成一个层次化的索引。
  • 设置与选取:掌握使用 set_index() 设置层级索引,以及使用 loc 通过外层和内层索引精确选取数据子集。
  • 索引操作:学习交换索引层级 (swaplevel) 和对层级索引进行排序 (sort_index)。
  • 应用场景:了解层级索引在分组操作和透视表生成中的重要作用。

理解层级索引

在之前的课程中,我们接触的 DataFrame 通常只有一个行索引(Index)。层级索引(MultiIndex),顾名思义,就是为数据行设置多个层级的索引标签。

想象一下“世界幸福指数”数据集:每个国家(Country)都有一个幸福指数排名和分数,而每个国家又归属于一个更大的地理区域(Region)。如果我们想同时按区域和国家来组织和查询数据,层级索引就非常有用。此时,区域(Region)可以作为外层索引,国家(Country)作为内层索引,形成一个两层的数据访问结构。

设置层级索引时,传入列的顺序至关重要。先传入的列会成为外层索引,后传入的成为内层索引。数据访问时,需要遵循“从外到内”的顺序。

设置与操作层级索引

让我们通过代码来具体学习。首先,我们构造一个模拟的“幸福指数”数据集进行演示。

import pandas as pd

# 构造示例数据:模拟幸福指数数据集
data = {
    'Region': ['Western Europe', 'Western Europe', 'Australia and New Zealand', 
               'Central and Eastern Europe', 'Western Europe'],
    'Country': ['Denmark', 'Switzerland', 'New Zealand', 'Czech Republic', 'Iceland'],
    'Happiness Rank': [1, 2, 8, 27, 3],
    'Happiness Score': [7.526, 7.509, 7.334, 6.609, 7.504]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
原始数据:
                       Region         Country  Happiness Rank  Happiness Score
0              Western Europe         Denmark               1            7.526
1              Western Europe     Switzerland               2            7.509
2   Australia and New Zealand     New Zealand               8            7.334
3  Central and Eastern Europe  Czech Republic              27            6.609
4              Western Europe         Iceland               3            7.504

设置层级索引

使用 DataFrame.set_index() 方法,并传入一个列名列表,即可设置层级索引。参数 inplace=True 表示直接在原 DataFrame 上修改。

import pandas as pd

# 重新构造数据,确保每个代码块自包含
data = {
    'Region': ['Western Europe', 'Western Europe', 'Australia and New Zealand', 
               'Central and Eastern Europe', 'Western Europe'],
    'Country': ['Denmark', 'Switzerland', 'New Zealand', 'Czech Republic', 'Iceland'],
    'Happiness Rank': [1, 2, 8, 27, 3],
    'Happiness Score': [7.526, 7.509, 7.334, 6.609, 7.504]
}
df = pd.DataFrame(data)

# 设置层级索引:Region为外层,Country为内层
df_multi = df.set_index(['Region', 'Country'])
print("\n设置层级索引后:")
print(df_multi)
设置层级索引后:
                                           Happiness Rank  Happiness Score
Region                     Country
Western Europe             Denmark                      1            7.526
                           Switzerland                  2            7.509
Australia and New Zealand  New Zealand                  8            7.334
Central and Eastern Europe Czech Republic              27            6.609
Western Europe             Iceland                      3            7.504

可以看到,索引变成了两层:第一层是 Region,第二层是 Country。属于同一个区域(如 Western Europe)的国家被“分组”在了一起,但它们在数据中的物理位置(行顺序)并未改变。

通过层级索引选取数据

选取数据时,需要使用 .loc[] 索引器。

  • 外层选取:只需提供外层索引的标签,可以获取该外层索引下的所有数据(一个分组)。
  • 内层选取:必须同时提供外层和内层索引的标签(以元组形式),才能定位到唯一的一行数据。
import pandas as pd

# 重新构造带层级索引的DataFrame
data = {
    'Region': ['Western Europe', 'Western Europe', 'Australia and New Zealand', 
               'Central and Eastern Europe', 'Western Europe'],
    'Country': ['Denmark', 'Switzerland', 'New Zealand', 'Czech Republic', 'Iceland'],
    'Happiness Rank': [1, 2, 8, 27, 3],
    'Happiness Score': [7.526, 7.509, 7.334, 6.609, 7.504]
}
df = pd.DataFrame(data)
df_multi = df.set_index(['Region', 'Country'])

# 外层选取:获取‘Western Europe’地区的所有国家数据
print("选取‘Western Europe’地区:")
print(df_multi.loc['Western Europe'])

# 内层选取:获取‘Australia and New Zealand’地区的‘New Zealand’数据
print("\n选取(‘Australia and New Zealand‘, ‘New Zealand‘):")
print(df_multi.loc[('Australia and New Zealand', 'New Zealand')])
选取‘Western Europe’地区:
             Happiness Rank  Happiness Score
Country
Denmark                   1            7.526
Switzerland               2            7.509
Iceland                   3            7.504

选取(‘Australia and New Zealand‘, ‘New Zealand‘):
Happiness Rank     8.000
Happiness Score    7.334
Name: (Australia and New Zealand, New Zealand), dtype: float64

重要提示:如果只传入内层索引标签(如 'New Zealand'),Pandas 会认为它是外层索引标签,由于在外层找不到匹配项,会导致 KeyError。

索引层级操作

交换索引层级

使用 swaplevel() 方法可以交换两个索引层级的位置。这在需要改变数据访问主维度时非常有用。

import pandas as pd

# 重新构造带层级索引的DataFrame
data = {
    'Region': ['Western Europe', 'Western Europe', 'Australia and New Zealand', 
               'Central and Eastern Europe', 'Western Europe'],
    'Country': ['Denmark', 'Switzerland', 'New Zealand', 'Czech Republic', 'Iceland'],
    'Happiness Rank': [1, 2, 8, 27, 3],
    'Happiness Score': [7.526, 7.509, 7.334, 6.609, 7.504]
}
df = pd.DataFrame(data)
df_multi = df.set_index(['Region', 'Country'])

# 交换索引层级,将Country变为外层,Region变为内层
df_swapped = df_multi.swaplevel()
print("交换索引层级后:")
print(df_swapped)
交换索引层级后:
                                           Happiness Rank  Happiness Score
Country        Region
Denmark        Western Europe                           1            7.526
Switzerland    Western Europe                           2            7.509
New Zealand    Australia and New Zealand                8            7.334
Czech Republic Central and Eastern Europe              27            6.609
Iceland        Western Europe                           3            7.504

层级索引排序

初始设置层级索引时,数据的物理顺序不变。使用 sort_index() 方法可以对索引进行排序,使得相同外层索引的数据物理上也聚集在一起,并且每一层内部都按字典序排列。

sort_index() 的 level 参数可以指定在哪一层级上进行排序。默认对所有层级排序(先排外层,再排内层)。

import pandas as pd

# 重新构造一个顺序更乱的示例数据
data = {
    'Region': ['Western Europe', 'Central and Eastern Europe', 'Western Europe', 
               'Australia and New Zealand', 'Western Europe'],
    'Country': ['Iceland', 'Czech Republic', 'Denmark', 'New Zealand', 'Switzerland'],
    'Happiness Rank': [3, 27, 1, 8, 2],
    'Happiness Score': [7.504, 6.609, 7.526, 7.334, 7.509]
}
df = pd.DataFrame(data)
df_multi = df.set_index(['Region', 'Country'])

print("原始层级索引(未排序):")
print(df_multi)

# 对层级索引进行排序(默认对所有层级排序)
df_sorted = df_multi.sort_index()
print("\n对索引排序后(先Region,后Country):")
print(df_sorted)

# 仅在内层索引(level=1)上进行排序
df_sorted_inner = df_multi.sort_index(level=1)
print("\n仅按内层索引(Country)排序:")
print(df_sorted_inner)
原始层级索引(未排序):
                                           Happiness Rank  Happiness Score
Region                     Country
Western Europe             Iceland                      3            7.504
Central and Eastern Europe Czech Republic              27            6.609
Western Europe             Denmark                      1            7.526
Australia and New Zealand  New Zealand                  8            7.334
Western Europe             Switzerland                  2            7.509

对索引排序后(先Region,后Country):
                                           Happiness Rank  Happiness Score
Region                     Country
Australia and New Zealand  New Zealand                  8            7.334
Central and Eastern Europe Czech Republic              27            6.609
Western Europe             Denmark                      1            7.526
                           Iceland                      3            7.504
                           Switzerland                  2            7.509

仅按内层索引(Country)排序:
                                           Happiness Rank  Happiness Score
Region                     Country
Central and Eastern Europe Czech Republic              27            6.609
Western Europe             Denmark                      1            7.526
                           Iceland                      3            7.504
Australia and New Zealand  New Zealand                  8            7.334
Western Europe             Switzerland                  2            7.509

排序后,数据首先按 Region 的字母顺序排列,然后在每个 Region 内部,再按 Country 的字母顺序排列。当仅按内层排序时,Country 顺序变了,但 Region 的组并未被打乱重排。

应用场景与总结

层级索引是 Pandas 中一个强大的数据组织工具,它主要应用于以下场景:

  1. 分组操作(GroupBy):为数据预先建立清晰的分组结构,使得后续的聚合分析(如求和、求平均)更加直观高效。
  2. 透视表(Pivot Table)的生成:透视表的结果行和列常常就是多层索引,便于从多个维度观察汇总数据。

掌握层级索引的创建、访问和基本操作,是迈向 Pandas 高阶数据分析的关键一步。它让处理具有真实世界层次关系的数据变得井然有序。

📝 动手练一练

  1. 概念辨析:在设置层级索引 df.set_index([‘A‘, ‘B‘]) 后,如果使用 df.loc[‘value_b‘] 进行选取却报错 KeyError,可能的原因是什么?
  2. 动手实践:请创建一个包含‘Class‘(班级)、‘Student‘(学生)、‘Score‘(分数)三列的 DataFrame,数据示例如下。然后完成以下操作:
    • 将‘Class‘和‘Student‘设置为层级索引(Class为外层)。
    • 取出‘A‘班所有学生的成绩。
    • 取出‘B‘班学生‘Bob‘的成绩。
    • 交换索引层级,查看结果。
ClassStudentScore
AAlice85
ATom92
BBob78
BJane88
👉 点击查看参考答案
  1. 可能的原因是:‘value_b‘ 是内层索引 ‘B‘ 列中的一个值,但使用 df.loc[‘value_b‘] 时,Pandas 会将其视为外层索引 ‘A‘ 列的值去查找。由于在外层索引中找不到 ‘value_b‘,因此引发 KeyError。正确的选取方式应为 df.loc[(‘value_a‘, ‘value_b‘)],同时指定外层和内层索引值。

  2. 动手实践参考答案:

import pandas as pd

# 构造数据
data_ex = {
    'Class': ['A', 'A', 'B', 'B'],
    'Student': ['Alice', 'Tom', 'Bob', 'Jane'],
    'Score': [85, 92, 78, 88]
}
df_ex = pd.DataFrame(data_ex)

# 设置层级索引
df_ex_multi = df_ex.set_index(['Class', 'Student'])
print("设置层级索引后:\n", df_ex_multi)

# a. 取出‘A‘班所有学生成绩
print("\na. A班成绩:\n", df_ex_multi.loc['A'])

# b. 取出‘B‘班学生‘Bob‘的成绩
print("\nb. B班Bob的成绩:\n", df_ex_multi.loc[('B', 'Bob')])

# c. 交换索引层级
df_ex_swapped = df_ex_multi.swaplevel()
print("\nc. 交换索引层级后:\n", df_ex_swapped)

预期输出:

设置层级索引后:
                Score
Class Student
A     Alice       85
      Tom         92
B     Bob         78
      Jane        88

a. A班成绩:
          Score
Student
Alice       85
Tom         92

b. B班Bob的成绩:
 Score    78
Name: (B, Bob), dtype: int64

c. 交换索引层级后:
                Score
Student Class
Alice   A         85
Tom     A         92
Bob     B         78
Jane    B         88

本章小结

本节我们深入学习了 Pandas 的层级索引(MultiIndex),它是处理具有层次结构数据的利器。

📋 行动清单

  • 练习设置:在你的数据中,尝试将两列有逻辑包含关系的列(如“省份”和“城市”)设置为层级索引。
  • 掌握选取:熟练使用 .loc[] 进行外层选取(单标签)和内层选取(元组标签)。
  • 尝试操作:对已有的层级索引数据,使用 swaplevel() 和 sort_index() 观察数据形态的变化,理解其作用。

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 本节课件:层级索引
    PDF · 280KB
    下载
  • 第6章配套代码包:分组聚合与数据规整示例
    ZIP · 0.6MB
    下载
  • 全套课件打包(第1-5章)
    ZIP · 12.8MB
    下载
  • 全套课件打包(第6-8章)
    ZIP · 15MB
    下载
  • 实战数据集:AppleStore 应用商城分析
    ZIP · 329KB
    下载
  • 实战数据集:女性服装电商分析
    ZIP · 2.8MB
    下载
  • Python 数据分析环境搭建指南
    PDF · 2MB
    下载
  • Scrapy 安装教程
    PDF · 12.7MB
    下载
  • 附加实战项目:AppleStore 应用商城数据分析
    ZIP · 0.3MB · ipynb + CSV 数据
    下载
  • 附加实战项目:银行电话营销数据分析
    ZIP · 0.4MB · ipynb + CSV 数据
    下载
  • 附加实战项目:女性服装电商评论数据分析
    ZIP · 2.7MB · ipynb + CSV 数据
    下载
  • 附加实战项目:美国化学学会杂志数据分析
    ZIP · 34.2MB · ipynb + SQLite 数据库
    下载