查看全课大纲(第 38 / 101 节)
- 1.数据分析基本概念
- 2.学习数据分析的一般路线
- 3.数据分析的流程
- 4.数据类型
- 5.环境部署(1)
- 6.环境部署(2)
- 7.课程介绍
- 8.TXT文件操作
- 9.JSON文件操作
- 10.CSV文件操作
- 11.Excel文件操作
- 12.数据库及SQL常用语法
- 13.数据库基本操作
- 14.数据库多表连接
- 15.实战:欧洲职业足球数据库分析
- 16.爬虫简介
- 17.URL管理模块
- 18.网页下载模块
- 19.网页解析模块(1)
- 20.网页解析模块(2)
- 21.Scrapy简介
- 22.Scrapy使用步骤(1)
- 23.Scrapy使用步骤(2)
- 24.Scrapy使用步骤(3)
- 25.Scrapy使用步骤(4)
- 26.实战:获取国内城市空气质量指数数据
- 27.NumPy和SciPy介绍
- 28.多维数组
- 29.多维数组操作
- 30.NumPy的常用方法
- 31.向量化介绍
- 32.向量化及通用函数
- 33.实战:2016美国大选分析
- 34.数据结构-Series
- 35.数据结构-DataFrame
- 36.数据结构-Index
- 37.Series的索引操作
- 38.DataFrame的索引操作
- 39.索引操作总结
- 40.运算与对齐
- 41.函数应用操作(1) -- map
- 42.函数应用操作 (2) -- apply applymap
- 43.文件读写操作
- 44.排序操作
- 45.数据清洗--处理缺失数据
- 46.数据清洗--处理重复数据
- 47.数据清洗--替换数据
- 48.常用统计方法(1) -- describe quantile
- 49.常用统计方法(2) -- sum mean median count
- 50.常用统计方法(3) -- max min idxmax idxmin
- 51.常用统计方法(4) -- mad var std cumsum
- 52.实战:全球食品数据分析
- 53.层级索引
- 54.分组与聚合介绍
- 55.分组操作(1) -- GroupBy对象及常用聚合操作
- 56.分组操作(2) -- 自定义分组及聚合操作
- 57.透视表介绍
- 58.透视表操作
- 59.数据规整(1) -- 数据合并concat
- 60.数据规整(2) -- 数据连接merge
- 61.数据重构(3) -- 数据重构stack unstack
- 62.实战:互联网电影资料库分析
- 63.探索性数据分析EDA介绍
- 64.EDA的目的
- 65.EDA常用工具
- 66.Matplotlib绘图基本介绍
- 67.Matplotlib画布
- 68.散点图和柱状图的绘制
- 69.直方图的绘制
- 70.矩阵绘图
- 71.子图的使用
- 72.Matplotlib颜色、标记、线型
- 73.Matplotlib坐标刻度、标签、图例、标题
- 74.Seaborn介绍
- 75.数据集分布可视化(1) -- 单变量分布、双变量分布
- 76.数据集分布可视化(2) -- 变量关系可视化
- 77.类别数据可视化 -- 类别散布图、类别内数据分布、类别内统计图
- 78.交互式数据可视化工具Bokeh介绍
- 79.Bokeh绘制散点图、柱状图、盒子图、弦图
- 80.Bokeh绘制常用图形元素
- 81.3D绘图 -- mplot3d
- 82.3D曲线可视化
- 83.3D散点图可视化
- 84.3D柱状图可视化
- 85.Pandas绘图
- 86.实战:Lending Club借贷数据探索性分析及可视化
- 87.机器学习介绍及应用场景
- 88.机器学习建模介绍 (1) -- 分类
- 89.机器学习建模介绍 (2) -- 回归
- 90.机器学习建模介绍 (3) -- 聚类
- 91.机器学习分类
- 92.机器学习工具scikit-learn
- 93.使用scikit-learn的流程
- 94.数据集准备及划分
- 95.模型选择
- 96.数据预处理及特征工程
- 97.过拟合与欠拟合
- 98.模型调参介绍
- 99.模型调参方法
- 100.模型测试及评价
- 101.实战:通过移动设备行为数据预测性别和年龄
DataFrame的索引操作
约 11 分钟
小象实战讲义 · Python数据分析实战
上一节我们详细学习了Series的索引操作,这一节我们来看一下DataFrame的索引操作。DataFrame作为二维表格结构,其索引方式比Series更加丰富,既有列索引也有行索引,还有混合索引。掌握这些索引操作是高效进行数据筛选和提取的基础。
💡 核心导读
- DataFrame的列索引:使用方括号直接获取单列或多列
- DataFrame的行索引:必须使用
.loc[](标签索引)或.iloc[](位置索引) - 混合索引:先行后列与先列后行的多种写法
inplace参数的作用:控制操作是否在原数据上直接修改
DataFrame的列索引
DataFrame在设计时更倾向于面向列的操作,因此直接使用方括号进行索引时,默认获取的是列数据。
import pandas as pd
import numpy as np
# 构建DataFrame
country1 = pd.Series({'Name': '中国',
'Language': 'Chinese',
'Area': '9.597M km2',
'Happiness Rank': 79})
country2 = pd.Series({'Name': '美国',
'Language': 'English (US)',
'Area': '9.834M km2',
'Happiness Rank': 14})
country3 = pd.Series({'Name': '澳大利亚',
'Language': 'English (AU)',
'Area': '7.692M km2',
'Happiness Rank': 9})
df = pd.DataFrame([country1, country2, country3], index=['CH', 'US', 'AU'])
print("完整DataFrame:")
print(df)
print()完整DataFrame:
Name Language Area Happiness Rank
CH 中国 Chinese 9.597M km2 79
US 美国 English (US) 9.834M km2 14
AU 澳大利亚 English (AU) 7.692M km2 9单列索引
获取单列时,直接在方括号中放入列名,返回的是一个Series对象:
import pandas as pd
# 重新构建DataFrame(每个代码块自包含)
country1 = pd.Series({'Name': '中国', 'Language': 'Chinese', 'Area': '9.597M km2', 'Happiness Rank': 79})
country2 = pd.Series({'Name': '美国', 'Language': 'English (US)', 'Area': '9.834M km2', 'Happiness Rank': 14})
country3 = pd.Series({'Name': '澳大利亚', 'Language': 'English (AU)', 'Area': '7.692M km2', 'Happiness Rank': 9})
df = pd.DataFrame([country1, country2, country3], index=['CH', 'US', 'AU'])
# 获取'Area'列
area_series = df['Area']
print("Area列数据:")
print(area_series)
print(f"类型: {type(area_series).__name__}")Area列数据:
CH 9.597M km2
US 9.834M km2
AU 7.692M km2
Name: Area, dtype: str
类型: Series多列索引
获取不连续的多列时,需要在方括号中放入列名的列表,返回的是一个DataFrame:
import pandas as pd
# 重新构建DataFrame
country1 = pd.Series({'Name': '中国', 'Language': 'Chinese', 'Area': '9.597M km2', 'Happiness Rank': 79})
country2 = pd.Series({'Name': '美国', 'Language': 'English (US)', 'Area': '9.834M km2', 'Happiness Rank': 14})
country3 = pd.Series({'Name': '澳大利亚', 'Language': 'English (AU)', 'Area': '7.692M km2', 'Happiness Rank': 9})
df = pd.DataFrame([country1, country2, country3], index=['CH', 'US', 'AU'])
# 获取'Area'和'Name'两列
area_name_df = df[['Area', 'Name']]
print("Area和Name两列数据:")
print(area_name_df)
print(f"类型: {type(area_name_df).__name__}")Area和Name两列数据:
Area Name
CH 9.597M km2 中国
US 9.834M km2 美国
AU 7.692M km2 澳大利亚
类型: DataFrameDataFrame的行索引
在DataFrame中进行行索引时,必须使用.loc[](基于标签)或.iloc[](基于位置),不能省略。这是因为DataFrame有两个索引方向(行和列),如果省略.loc/.iloc,Python会将其解释为列索引。
import pandas as pd
# 重新构建DataFrame
country1 = pd.Series({'Name': '中国', 'Language': 'Chinese', 'Area': '9.597M km2', 'Happiness Rank': 79})
country2 = pd.Series({'Name': '美国', 'Language': 'English (US)', 'Area': '9.834M km2', 'Happiness Rank': 14})
country3 = pd.Series({'Name': '澳大利亚', 'Language': 'English (AU)', 'Area': '7.692M km2', 'Happiness Rank': 9})
df = pd.DataFrame([country1, country2, country3], index=['CH', 'US', 'AU'])
# 获取行标签为'CH'的行(中国)
row_ch = df.loc['CH']
print("行标签'CH'的数据:")
print(row_ch)
print(f"类型: {type(row_ch).__name__}")
print()
# 获取第一行(位置0,即中国)
row_first = df.iloc[0]
print("位置0(第一行)的数据:")
print(row_first)
print(f"类型: {type(row_first).__name__}")行标签'CH'的数据:
Name 中国
Language Chinese
Area 9.597M km2
Happiness Rank 79
Name: CH, dtype: object
类型: Series
位置0(第一行)的数据:
Name 中国
Language Chinese
Area 9.597M km2
Happiness Rank 79
Name: CH, dtype: object
类型: Series注意:无论是获取一列还是一行,返回的都是Series类型,因为它们都是一维数据。
混合索引
混合索引指的是同时指定行和列来获取特定单元格的数据。有两种方式:先行后列和先列后行。
先行后列
先使用.loc[]或.iloc[]获取行(得到一个Series),再从这个Series中获取列:
import pandas as pd
# 重新构建DataFrame
country1 = pd.Series({'Name': '中国', 'Language': 'Chinese', 'Area': '9.597M km2', 'Happiness Rank': 79})
country2 = pd.Series({'Name': '美国', 'Language': 'English (US)', 'Area': '9.834M km2', 'Happiness Rank': 14})
country3 = pd.Series({'Name': '澳大利亚', 'Language': 'English (AU)', 'Area': '7.692M km2', 'Happiness Rank': 9})
df = pd.DataFrame([country1, country2, country3], index=['CH', 'US', 'AU'])
# 方法1: 先行后列
value1 = df.loc['CH']['Area']
print(f"df.loc['CH']['Area'] = {value1}")
# 使用iloc同理
value2 = df.iloc[0]['Area'] # iloc[0]对应第一行'CH'
print(f"df.iloc[0]['Area'] = {value2}")df.loc['CH']['Area'] = 9.597M km2
df.iloc[0]['Area'] = 9.597M km2先列后行
先获取列(得到一个Series),再从这个Series中获取行:
import pandas as pd
# 重新构建DataFrame
country1 = pd.Series({'Name': '中国', 'Language': 'Chinese', 'Area': '9.597M km2', 'Happiness Rank': 79})
country2 = pd.Series({'Name': '美国', 'Language': 'English (US)', 'Area': '9.834M km2', 'Happiness Rank': 14})
country3 = pd.Series({'Name': '澳大利亚', 'Language': 'English (AU)', 'Area': '7.692M km2', 'Happiness Rank': 9})
df = pd.DataFrame([country1, country2, country3], index=['CH', 'US', 'AU'])
# 方法2: 先列后行
value3 = df['Area']['CH']
print(f"df['Area']['CH'] = {value3}")
# 在得到的Series上,可以加.loc或.iloc,效果一样
value4 = df['Area'].loc['CH']
print(f"df['Area'].loc['CH'] = {value4}")
value5 = df['Area'].iloc[0]
print(f"df['Area'].iloc[0] = {value5}")df['Area']['CH'] = 9.597M km2
df['Area'].loc['CH'] = 9.597M km2
df['Area'].iloc[0] = 9.597M km2两种方式的结果相同,选择哪种取决于个人习惯和代码可读性。
inplace参数的作用
Pandas中的很多操作(如drop()、replace()等)都有一个重要的参数inplace,它控制操作是否在原数据上直接修改。
默认行为:inplace=False
当inplace=False(默认值)时,操作会返回一个新的对象,原始数据保持不变:
import pandas as pd
# 创建新的DataFrame用于演示
country1 = pd.Series({'Name': '中国', 'Language': 'Chinese', 'Area': '9.597M km2', 'Happiness Rank': 79})
country2 = pd.Series({'Name': '美国', 'Language': 'English (US)', 'Area': '9.834M km2', 'Happiness Rank': 14})
country3 = pd.Series({'Name': '澳大利亚', 'Language': 'English (AU)', 'Area': '7.692M km2', 'Happiness Rank': 9})
df_demo = pd.DataFrame([country1, country2, country3], index=['CH', 'US', 'AU'])
print("原始数据:")
print(df_demo)
print()
# 删除Area列,默认inplace=False
df_new = df_demo.drop('Area', axis=1)
print("删除Area列后的新DataFrame:")
print(df_new)
print()
print("原始数据是否改变?")
print(df_demo)原始数据:
Name Language Area Happiness Rank
CH 中国 Chinese 9.597M km2 79
US 美国 English (US) 9.834M km2 14
AU 澳大利亚 English (AU) 7.692M km2 9
删除Area列后的新DataFrame:
Name Language Happiness Rank
CH 中国 Chinese 79
US 美国 English (US) 14
AU 澳大利亚 English (AU) 9
原始数据是否改变?
Name Language Area Happiness Rank
CH 中国 Chinese 9.597M km2 79
US 美国 English (US) 9.834M km2 14
AU 澳大利亚 English (AU) 7.692M km2 9直接修改:inplace=True
当inplace=True时,操作会在原数据上直接修改,且没有返回值(返回None):
import pandas as pd
# 创建新的DataFrame用于演示
country1 = pd.Series({'Name': '中国', 'Language': 'Chinese', 'Area': '9.597M km2', 'Happiness Rank': 79})
country2 = pd.Series({'Name': '美国', 'Language': 'English (US)', 'Area': '9.834M km2', 'Happiness Rank': 14})
country3 = pd.Series({'Name': '澳大利亚', 'Language': 'English (AU)', 'Area': '7.692M km2', 'Happiness Rank': 9})
df_inplace = pd.DataFrame([country1, country2, country3], index=['CH', 'US', 'AU'])
print("操作前数据:")
print(df_inplace)
print()
# 删除Area列,inplace=True
result = df_inplace.drop('Area', axis=1, inplace=True)
print(f"drop操作返回值: {result}")
print()
print("操作后数据(已直接修改):")
print(df_inplace)操作前数据:
Name Language Area Happiness Rank
CH 中国 Chinese 9.597M km2 79
US 美国 English (US) 9.834M km2 14
AU 澳大利亚 English (AU) 7.692M km2 9
drop操作返回值: None
操作后数据(已直接修改):
Name Language Happiness Rank
CH 中国 Chinese 79
US 美国 English (US) 14
AU 澳大利亚 English (AU) 9重要提示:
inplace=False(默认):安全,原始数据不变,需要用变量接收结果inplace=True:直接修改原始数据,无返回值,使用时需谨慎- 如果对
inplace=True的操作结果用变量接收,该变量的值会是None
📝 动手练一练
- 概念辨析:在DataFrame中,为什么行索引必须使用
.loc[]或.iloc[],而列索引可以直接用方括号?
👉 点击查看参考答案
因为DataFrame有两个索引方向(行和列)。当使用方括号时,Pandas默认将其解释为列索引。如果省略.loc/.iloc,像df['CH']这样的写法会被理解为获取名为’CH’的列,而不是行。使用.loc[]和.iloc[]可以明确指定我们要进行的是行索引操作。
相比之下,Series只有一个索引方向(行索引),所以可以直接用方括号而不会产生歧义。
- 代码实践:创建一个包含学生成绩的DataFrame,然后:
- 使用列索引获取”数学”成绩列
- 使用行索引获取”李四”的所有成绩
- 使用混合索引获取”王五”的”英语”成绩
- 使用
drop()方法删除”语文”列(用两种方式:创建新对象和直接修改)
👉 点击查看参考答案
import pandas as pd
# 创建学生成绩DataFrame
scores = pd.DataFrame({
'语文': [85, 92, 78],
'数学': [90, 88, 95],
'英语': [88, 85, 92]
}, index=['张三', '李四', '王五'])
print("原始数据:")
print(scores)
print()
# 1. 获取"数学"成绩列
math_scores = scores['数学']
print("数学成绩列:")
print(math_scores)
print(f"类型: {type(math_scores).__name__}")
print()
# 2. 获取"李四"的所有成绩
li_si_scores = scores.loc['李四']
print("李四的所有成绩:")
print(li_si_scores)
print(f"类型: {type(li_si_scores).__name__}")
print()
# 3. 获取"王五"的"英语"成绩
wang_wu_english = scores.loc['王五']['英语'] # 或 scores['英语']['王五']
print("王五的英语成绩:", wang_wu_english)
print()
# 4. 删除"语文"列(两种方式)
# 方式1:创建新对象(默认inplace=False)
scores_no_chinese = scores.drop('语文', axis=1)
print("方式1 - 删除语文列后的新DataFrame:")
print(scores_no_chinese)
print("原始数据不变:")
print(scores)
print()
# 方式2:直接修改(inplace=True)
scores_copy = scores.copy() # 先复制一份,避免修改原始数据
scores_copy.drop('语文', axis=1, inplace=True)
print("方式2 - 直接修改后:")
print(scores_copy)原始数据:
语文 数学 英语
张三 85 90 88
李四 92 88 85
王五 78 95 92
数学成绩列:
张三 90
李四 88
王五 95
Name: 数学, dtype: int64
类型: Series
李四的所有成绩:
语文 92
数学 88
英语 85
Name: 李四, dtype: int64
类型: Series
王五的英语成绩: 92
方式1 - 删除语文列后的新DataFrame:
数学 英语
张三 90 88
李四 88 85
王五 95 92
原始数据不变:
语文 数学 英语
张三 85 90 88
李四 92 88 85
王五 78 95 92
方式2 - 直接修改后:
数学 英语
张三 90 88
李四 88 85
王五 95 92本章小结
本节我们深入学习了DataFrame的索引操作,这是Pandas数据操作的核心技能之一。掌握这些索引方式,能够帮助我们高效地从复杂的数据集中提取所需信息。
📋 行动清单
- 练习DataFrame的列索引:使用方括号获取单列和多列数据
- 掌握行索引的两种方式:
.loc[]用于标签索引,.iloc[]用于位置索引 - 尝试混合索引:分别用先行后列和先列后行的方式获取特定单元格数据
- 理解
inplace参数:区分创建新对象和直接修改原数据的场景
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。
- 下载本节课件:DataFrame的索引操作PDF · 264KB
- 下载全套课件打包(第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 数据库