📌 写在前面
大家好!
欢迎来到**【一起学Python】**的第79天!
前五天我们一步步打下了坚实基础:安装环境 → 认识ndarray → 掌握数据类型 → 熟悉数组属性 → 高效创建数组。今天,我们要解锁数据分析中最核心、最高频的技能之一:切片与索引!
为什么要学切片与索引?
- ✅ 数据分析的第一步永远是**“取数据”**
- ✅ 掌握索引,你能秒级提取百万行中的特定样本
- ✅ 布尔索引 & 花式索引是数据清洗、特征筛选的神器
- ✅ 避免“视图 vs 副本”陷阱,防止悄悄改坏原始数据
今天你将学到:
- 🔸 1D/2D/3D数组的基础索引语法
- 🔸 切片操作与步长控制技巧
- 🔸 布尔索引:按条件精准筛选
- 花式索引:自定义位置提取
准备好了吗?让我们开始吧!👇
一、基础索引:精准定位数据 🔍
NumPy的索引语法简洁高效,记住核心规则:用逗号分隔维度,而不是连续的中括号!
1.1 一维数组索引
import numpy as npone_d = np.array([10, 20, 30, 40, 50])print("一维数组:", one_d)print("第一个元素:", one_d[0]) # 10print("最后一个元素:", one_d[-1]) # 50
1.2 二维数组索引(最常用)
two_d = np.array([[1, 2, 3], [4, 5, 6]])print("二维数组:\n", two_d)# ✅ 推荐写法:逗号分隔行列print("第1行第2列:", two_d[0, 1]) # 2print("第2行第3列:", two_d[1, 2]) # 6# ❌ 不推荐:two_d[0][1](性能更低,可读性差)
1.3 三维数组索引
three_d = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])print("三维数组:\n", three_d)# 格式:[块, 行, 列]print("第1块第2行第1列:", three_d[0, 1, 0]) # 3
💡 记忆口诀:arr[维度1, 维度2, 维度3...],逗号是关键!二、切片操作:批量提取的艺术 ️
切片是NumPy的“批量处理”核心,语法与Python列表一致,但支持多维!
2.1 基础切片语法
arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])# 取前两行,前三列print(arr[:2, :3])# 输出:# [[1 2 3]# [6 7 8]]# 取所有行,第2到4列print(arr[:, 1:4])# 输出:# [[2 3 4]# [7 8 9]]
2.2 步长切片(反向/跳跃提取)
# 第一行,每隔一个元素取print("步长切片:", arr[0, ::2]) # [1 3 5]# 反向取整行print("反向切片:", arr[0, ::-1]) # [5 4 3 2 1]# 跨维度步长:每2行取1行,每3列取1列print(arr[::2, ::3])
💡 核心规则:
start:stop:step,省略则取默认值: 代表“全选该维度”- 负数步长表示反向提取
三、高级索引:数据分析的“超级武器” 🚀
当基础切片不够用时,NumPy提供了两种高级索引方式,是数据清洗的必备技能!
3.1 布尔索引(条件筛选之王)
通过条件表达式生成布尔数组,直接过滤数据。
data = np.array([10, 20, 30, 40, 50])# 生成布尔条件condition = data > 25print("条件结果:", condition) # [False False True True True]# 方式1:先存条件再提取filtered1 = data[condition]print("筛选结果1:", filtered1) # [30 40 50]# 方式2:一步到位(最常用!)filtered2 = data[data < 30]print("筛选结果2:", filtered2) # [10 20]# 🔥 实战:二维数组按条件筛选matrix = np.array([[1, 5, 3], [8, 2, 9]])print("大于4的元素:", matrix[matrix > 4]) # [5 8 9]
3.2 花式索引(Fancy Indexing)
使用整数数组指定要提取的具体位置,非常灵活!
arr = np.array([10, 20, 30, 40, 50])indices = np.array([0, 2, 4]) # 指定要取的位置print("花式索引:", arr[indices]) # [10 30 50]
two_d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])row_idx = np.array([0, 2]) # 第0行、第2行col_idx = np.array([1, 1]) # 第1列、第1列# 提取坐标:(0,1) 和 (2,1)print("二维花式索引:", two_d[row_idx, col_idx]) # [2 8]
⚠️ 重要区别:
two_d[[0,2], 1] → 取第0行和第2行的第1列,返回二维子数组two_d[[0,2], [1,1]] → 按坐标配对提取,返回一维数组
四、新手避坑指南 ⚠️
❌ 坑1:切片是“视图”,修改会改原数组!
arr = np.array([1, 2, 3, 4, 5])sub = arr[1:4] # 切片返回的是视图(View)sub[0] = 99print("原数组:", arr) # [ 1 99 3 4 5] ️ 原数组被改了!# ✅ 解决方案:需要独立副本时使用 .copy()sub_copy = arr[1:4].copy()sub_copy[0] = 88print("原数组不变:", arr) # [1 2 3 4 5] ✅
❌ 坑2:花式索引/布尔索引返回的是“副本”
data = np.array([10, 20, 30])mask = data[data > 15]mask[0] = 999 # 修改的是副本,不影响原数组print("原数组:", data) # [10 20 30] ✅ 安全!
❌ 坑3:索引越界直接报错,不像Python列表可容忍
arr = np.array([1, 2, 3])# print(arr[5]) # IndexError: index 5 is out of bounds
📝 今日作业
基础题 ⭐
- 创建一个5×5的矩阵,提取第2行、第3列、以及中心3×3的子矩阵
- 使用切片将一维数组
[0,1,2,3,4,5,6,7,8,9] 逆序输出 - 提取数组中所有偶数位置的元素(步长切片)
进阶题 ⭐⭐
- 生成100个随机数,使用布尔索引筛选出大于0.5的数,并计算平均值
- 创建一个4×4矩阵,用花式索引提取四个角的元素
- 对比
arr[1:3].copy() 和 arr[1:3] 的内存地址(使用 id())
挑战题 ⭐⭐⭐
- 模拟学生成绩表:3行(学生)×4列(科目),筛选出平均分>80的学生所在行
- 实现“条件替换”:将数组中小于0的值替换为0,大于10的值替换为10
- 编写函数:输入任意二维数组和阈值,返回大
import numpy as np# 基础题arr = np.arange(10)print("逆序:", arr[::-1])print("偶数位:", arr[::2])# 进阶题data = np.random.rand(100)filtered = data[data > 0.5]print("均值:", np.mean(filtered))# 挑战题:条件替换arr = np.array([-1, 5, 12, 3, -4])arr[arr < 0] = 0arr[arr > 10] = 10print("替换后:", arr)
🎓 明日预告
第80天:NumPy数组运算与广播机制
你将学到:
- 🔸 数组的加减乘除与数学函数
- 🔸 广播机制(Broadcasting)核心原理
- 矩阵乘法 vs 元素级乘法
- 实战:无需循环的向量化计算
敬请期待!
💡 学习小贴士
- 索引选择指南:
- 取连续区域 → 用切片
start:stop - 按条件筛选 → 用布尔索引
arr[arr > x] - 按指定位置取 → 用花式索引
arr[[i, j, k]]
- 性能优化:
- 始终优先使用
arr[i, j] 而非 arr[i][j] - 大数据集避免在循环中反复切片
- 需要修改切片时,记得
.copy() 防污染
- 调试技巧:
- 形状对不上?先
print(arr.shape) - 改数据影响原数组?检查是否是视图
- 索引报错?确认维度数和边界
📚 学习路线图
第74天:NumPy安装 ✓第75天:ndarray对象 ✓第76天:数据类型 ✓第77天:数组属性 ✓第78天:创建数组 ✓第79天:切片和索引 ✓ ← 你今天在这里第80天:数组运算第81天:广播机制第82天:统计函数...
💬 写在最后
切片与索引是NumPy的**“数据导航仪”**,掌握它们,你就能:
✅ 精准定位任意维度的数据✅ 秒级完成条件筛选与批量提取✅ 避开视图/副本的经典陷阱
今天重点掌握:
- ✅ 逗号分隔的多维索引语法
- ✅ 布尔索引的一行筛选技巧
- ✅ 视图 vs 副本的区别与
.copy() 的使用
如果觉得有用,记得:
- 👍 点赞支持一下
- ⭐ 收藏方便复习
- 📤 分享给更多小伙伴
完成作业的同学,欢迎在评论区打卡! 💪
【一起学Python】每天进步一点点,365天后遇见更优秀的自己!
👉 关注公众号,不错过每天的学习内容!
🎯 今日金句:
"索引是数据的钥匙,切片是提取的艺术。掌握它们,百万行数据任你穿梭!" 🔑
明天见! 🌟