发布于2026-07-29 阅读(0)
扫一扫,手机访问
NumPy 的索引能力远不是 Python 列表能比的——基本索引、切片、花式索引、布尔索引,一套组合拳下来,数据操作变得异常灵活。下面从头梳理这些技巧,代码即学即用。
import numpy as np arr = np.array([10, 20, 30, 40, 50, 60]) # 基本索引 print(arr[0]) # 10 print(arr[-1]) # 60(倒数第一) print(arr[-2]) # 50 # 切片(返回视图,非副本!) print(arr[1:4]) # [20 30 40] print(arr[:3]) # [10 20 30](前 3 个) print(arr[3:]) # [40 50 60](从第 3 个到最后) print(arr[::2]) # [10 30 50](步长 2) print(arr[::-1]) # [60 50 40 30 20 10](反转) # 切片赋值(会修改原数组!) arr[1:4] = 99 print(arr) # [10 99 99 99 50 60]
mat = np.arange(12).reshape(3, 4) print(mat) # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] # 单个元素 print(mat[0, 0]) # 0 print(mat[2, -1]) # 11 # 整行 / 整列 print(mat[1]) # [4 5 6 7](第 1 行) print(mat[1, :]) # 同上 print(mat[:, 2]) # [ 2 6 10](第 2 列) # 子矩阵(切片) print(mat[0:2, 1:3]) # [[1 2] # [5 6]] # 步长切片 print(mat[::2, ::2]) # 每隔一行、每隔一列 # [[ 0 2] # [ 8 10]] # 行 + 列混合 print(mat[0, :2]) # [0 1](第 0 行前 2 列) print(mat[:2, -1]) # [3 7](前 2 行最后 1 列)
tensor = np.arange(24).reshape(2, 3, 4) # shape: (2, 3, 4) — 2 个矩阵,每个 3×4 print(tensor[0]) # 第一个 3×4 矩阵 print(tensor[0, 1]) # 第一个矩阵的第 1 行 → (4,) print(tensor[0, 1, 2]) # 标量 → 6 print(tensor[:, 0, :]) # 每个矩阵的第 0 行 → (2, 4) print(tensor[:, :, ::2]) # 每矩阵每隔一列 → (2, 3, 2)
arr = np.arange(120).reshape(2, 3, 4, 5) # 等价写法 print(arr[0, :, :, :]) # 完整写法 print(arr[0, ...]) # 用 ... 代替中间的 : print(arr[..., 2]) # 最后一个维度的第 2 索引 → (2, 3, 4) print(arr[0, ..., :3]) # 第一个块,最后维取前 3 → (3, 4, 3)
用整数数组来索引,返回副本(非视图)。这点和切片完全不同,后面会对比。
arr = np.array([10, 20, 30, 40, 50]) # 用列表指定索引 print(arr[[0, 2, 4]]) # [10 30 50] # 可以用任意整数数组 indices = np.array([4, 1, 1, 3]) print(arr[indices]) # [50 20 20 40] # 可以任意顺序、重复 print(arr[[4, 4, 4, 0, 0]]) # [50 50 50 10 10]
mat = np.arange(12).reshape(3, 4) # 指定行索引 print(mat[[0, 2]]) # 第 0 行和第 2 行 # [[ 0 1 2 3] # [ 8 9 10 11]] # 指定行 + 列索引 print(mat[[0, 2, 1], [0, 3, 1]]) # 取 (0,0), (2,3), (1,1) → [0 11 5] # ix_: 取行和列的笛卡尔积(子矩阵) print(mat[np.ix_([0, 2], [1, 3])]) # [[ 1 3] # [ 9 11]] # ix_ 等价于 mat[[0,2]][:, [1,3]]
mat = np.arange(12).reshape(3, 4) # 切片返回视图 view = mat[:2, :2] view[0, 0] = 99 print(mat[0, 0]) # 99 ← 原数组被修改了! # 花式索引返回副本 copy = mat[[0, 1]][:, [0, 1]] copy[0, 0] = 999 print(mat[0, 0]) # 99 ← 原数组未修改
arr = np.array([15, 3, 8, 22, 1, 9, 13]) # 条件直接筛选 print(arr[arr > 10]) # [15 22 13] # 多条件(用 & | ~,必须加括号!) print(arr[(arr > 5) & (arr < 20)]) # [15 8 9 13] print(arr[(arr < 5) | (arr > 20)]) # [3 22 1] print(arr[~(arr > 10)]) # [3 8 1 9] # ⚠️ 常见错误:用 and/or 或不加括号 # arr[arr > 5 and arr < 20] ← 报错! # arr[arr > 5 & arr < 20] ← 结果错误(& 优先级高)! # arr[(arr > 5) & (arr < 20)] ← 正确!
mat = np.arange(12).reshape(3, 4) # 按条件筛选行 print(mat[mat[:, 0] > 3]) # 第 0 列 >3 的行 # [[ 4 5 6 7] # [ 8 9 10 11]] # 整体条件 mask = mat > 5 print(mat[mask]) # [6 7 8 9 10 11](返回一维数组)
arr = np.array([15, 3, 8, 22, 1, 9, 13]) arr[arr > 10] = 0 # 所有 >10 的变 0 print(arr) # [0 3 8 0 1 9 0] arr[arr < 5] = -1 # 所有 <5 的变 -1 print(arr) # [-1 -1 8 0 -1 9 -1]
arr = np.array([15, 3, 8, 22, 1, 9, 13]) # where(条件, True时的值, False时的值) result = np.where(arr > 10, 1, 0) print(result) # [1 0 0 1 0 0 1] result = np.where(arr > 10, arr, -arr) print(result) # [ 1 -3 -8 1 -1 -9 1]
arr = np.array([15, 3, 8, 22, 1, 9, 13]) # 找到满足条件的索引 indices = np.where(arr > 10) print(indices) # (array([0, 3, 6]),) ← 返回元组! print(indices[0]) # [0 3 6](一维时) print(arr[indices]) # [15 22 13] # 二维 mat = np.arange(12).reshape(3, 4) rows, cols = np.where(mat > 5) print(rows) # [1 1 2 2 2 2] — 行索引 print(cols) # [2 3 0 1 2 3] — 列索引 print(mat[rows, cols]) # [6 7 8 9 10 11] — 值
# np.where 也可以处理多条件 arr = np.arange(10) result = np.where((arr > 3) & (arr < 8), arr * 10, arr) print(result) # [0 1 2 3 40 50 60 70 8 9]
arr = np.array([0, 5, 0, 3, 0, 8, 0]) print(np.argwhere(arr > 0)) # [[1] # [3] # [5]] # 和 where 的区别:argwhere 返回 (N, ndim) 数组,where 返回元组
arr = np.array([10, 20, 30, 40, 50]) # take: 按索引取值 print(arr.take([0, 2, 4])) # [10 30 50] print(np.take(arr, [4, 3, 3])) # [50 40 40] # 二维按轴取 mat = np.arange(12).reshape(3, 4) print(np.take(mat, [0, 2], axis=0)) # 取第 0、2 行 print(np.take(mat, [0, 2], axis=1)) # 取第 0、2 列 # put: 按索引设值(原地修改) arr = np.array([10, 20, 30, 40, 50]) np.put(arr, [0, 2], [99, 88]) print(arr) # [99 20 88 40 50]
# select: 多条件多选择 arr = np.array([15, 3, 8, 22, 1, 9, 13]) conditions = [arr < 5, arr > 15, True] # True = 兜底 choices = [-1, 1, 0] result = np.select(conditions, choices) print(result) # [0 -1 0 1 -1 0 0] # clip: 限制在范围内 print(np.clip(arr, 5, 15)) # [15 5 8 15 5 9 13] print(arr.clip(5, 15)) # 同上(方法形式)
mat = np.arange(12).reshape(3, 4) # 提取对角线 print(np.diag(mat)) # [0 5 10] print(np.diag(mat, k=1)) # [1 6 11](上对角线) # 提取上三角 / 下三角 print(np.triu(mat)) # 上三角(含对角线) print(np.tril(mat, k=-1)) # 下三角(不含对角线) # 索引数组组合 row_indices = np.array([0, 1, 2]) col_indices = np.array([3, 2, 1]) print(mat[row_indices, col_indices]) # [3 6 9] — 取 (0,3),(1,2),(2,1)
mat = np.arange(12).reshape(3, 4) # 取每行最大值的索引对应的列 col_idx = mat.argmax(axis=1) # [3 3 3] result = np.take_along_axis(mat, col_idx[:, None], axis=1) print(result) # [[3] [7] [11]]
| 需求 | 代码 |
|---|---|
| 单个元素 | arr[0, 1] / arr[-1] |
| 整行/列 | arr[1, :] / arr[:, 2] |
| 子矩阵 | arr[0:2, 1:3] |
| 步长切片 | arr[::2, ::3] |
| 反转 | arr[::-1] |
| 省略号 | arr[0, ..., :3] |
| 花式行索引 | arr[[0, 2, 4]] |
| 笛卡尔积索引 | arr[np.ix_([0,2], [1,3])] |
| 布尔筛选 | arr[arr > 10] |
| 多条件 | arr[(a>3) & (a<10)] |
| 条件替换 | np.where(arr > 0, 1, -1) |
| 条件查找 | np.where(arr > 0) |
| 列表取值 | np.take(arr, [0, 2]) |
| 多条件选择 | np.select(conds, choices) |
| 裁剪 | np.clip(arr, lo, hi) |
[[numpy-总览|← 返回总览]]
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8