Python-numpy-索引与切片

Python-numpy-索引与切片 NumPy 索引与切片NumPy 提供了比 Python list 强大得多的索引能力基本索引、切片、花式索引Fancy Indexing、布尔索引。 基本索引与切片一维数组importnumpyasnp arrnp.array([10,20,30,40,50,60])# 基本索引print(arr[0])# 10print(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]步长 2print(arr[::-1])# [60 50 40 30 20 10]反转# 切片赋值会修改原数组arr[1:4]99print(arr)# [10 99 99 99 50 60]二维数组matnp.arange(12).reshape(3,4)print(mat)# [[ 0 1 2 3]# [ 4 5 6 7]# [ 8 9 10 11]]# 单个元素print(mat[0,0])# 0print(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 列三维及以上tensornp.arange(24).reshape(2,3,4)# shape: (2, 3, 4) — 2 个矩阵每个 3×4print(tensor[0])# 第一个 3×4 矩阵print(tensor[0,1])# 第一个矩阵的第 1 行 → (4,)print(tensor[0,1,2])# 标量 → 6print(tensor[:,0,:])# 每个矩阵的第 0 行 → (2, 4)print(tensor[:,:,::2])# 每矩阵每隔一列 → (2, 3, 2)...Ellipsis省略号arrnp.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) 花式索引Fancy Indexing用整数数组来索引返回副本非视图。一维花式索引arrnp.array([10,20,30,40,50])# 用列表指定索引print(arr[[0,2,4]])# [10 30 50]# 可以用任意整数数组indicesnp.array([4,1,1,3])print(arr[indices])# [50 20 20 40]# 可以任意顺序、重复print(arr[[4,4,4,0,0]])# [50 50 50 10 10]二维花式索引matnp.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]]花式索引 vs 切片matnp.arange(12).reshape(3,4)# 切片返回视图viewmat[:2,:2]view[0,0]99print(mat[0,0])# 99 ← 原数组被修改了# 花式索引返回副本copymat[[0,1]][:,[0,1]]copy[0,0]999print(mat[0,0])# 99 ← 原数组未修改 布尔索引 ⭐arrnp.array([15,3,8,22,1,9,13])# 条件直接筛选print(arr[arr10])# [15 22 13]# 多条件用 | ~必须加括号print(arr[(arr5)(arr20)])# [15 8 9 13]print(arr[(arr5)|(arr20)])# [3 22 1]print(arr[~(arr10)])# [3 8 1 9]# ⚠️ 常见错误用 and/or 或不加括号# arr[arr 5 and arr 20] ← 报错# arr[arr 5 arr 20] ← 结果错误 优先级高# arr[(arr 5) (arr 20)] ← 正确二维布尔索引matnp.arange(12).reshape(3,4)# 按条件筛选行print(mat[mat[:,0]3])# 第 0 列 3 的行# [[ 4 5 6 7]# [ 8 9 10 11]]# 整体条件maskmat5print(mat[mask])# [6 7 8 9 10 11]返回一维数组布尔掩码赋值arrnp.array([15,3,8,22,1,9,13])arr[arr10]0# 所有 10 的变 0print(arr)# [0 3 8 0 1 9 0]arr[arr5]-1# 所有 5 的变 -1print(arr)# [-1 -1 8 0 -1 9 -1]np.where()— 条件索引三剑客条件替换三元运算arrnp.array([15,3,8,22,1,9,13])# where(条件, True时的值, False时的值)resultnp.where(arr10,1,0)print(result)# [1 0 0 1 0 0 1]resultnp.where(arr10,arr,-arr)print(result)# [ 1 -3 -8 1 -1 -9 1]条件查找返回索引arrnp.array([15,3,8,22,1,9,13])# 找到满足条件的索引indicesnp.where(arr10)print(indices)# (array([0, 3, 6]),) ← 返回元组print(indices[0])# [0 3 6]一维时print(arr[indices])# [15 22 13]# 二维matnp.arange(12).reshape(3,4)rows,colsnp.where(mat5)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 也可以处理多条件arrnp.arange(10)resultnp.where((arr3)(arr8),arr*10,arr)print(result)# [0 1 2 3 40 50 60 70 8 9]np.argwhere()— 获取非零/True 索引arrnp.array([0,5,0,3,0,8,0])print(np.argwhere(arr0))# [[1]# [3]# [5]]# 和 where 的区别argwhere 返回 (N, ndim) 数组where 返回元组np.take()/np.put()— 按索引取值/设值arrnp.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]# 二维按轴取matnp.arange(12).reshape(3,4)print(np.take(mat,[0,2],axis0))# 取第 0、2 行print(np.take(mat,[0,2],axis1))# 取第 0、2 列# put: 按索引设值原地修改arrnp.array([10,20,30,40,50])np.put(arr,[0,2],[99,88])print(arr)# [99 20 88 40 50]np.select()/np.clip()— 多条件/裁剪# select: 多条件多选择arrnp.array([15,3,8,22,1,9,13])conditions[arr5,arr15,True]# True 兜底choices[-1,1,0]resultnp.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))# 同上方法形式 多维索引技巧按行列号取值matnp.arange(12).reshape(3,4)# 提取对角线print(np.diag(mat))# [0 5 10]print(np.diag(mat,k1))# [1 6 11]上对角线# 提取上三角 / 下三角print(np.triu(mat))# 上三角含对角线print(np.tril(mat,k-1))# 下三角不含对角线# 索引数组组合row_indicesnp.array([0,1,2])col_indicesnp.array([3,2,1])print(mat[row_indices,col_indices])# [3 6 9] — 取 (0,3),(1,2),(2,1)按轴索引take_along_axismatnp.arange(12).reshape(3,4)# 取每行最大值的索引对应的列col_idxmat.argmax(axis1)# [3 3 3]resultnp.take_along_axis(mat,col_idx[:,None],axis1)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[(a3) (a10)]条件替换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-总览|← 返回总览]]