Python NumPy数组元素访问与增删改查详解
本文详细讲解Python NumPy库中ndarray数组的元素访问机制与增删改查操作。涵盖切片规则、行列索引方法,以及append、insert、concatenate等常用添加函数,结合delete、布尔过滤实现精准删除,并说明直接赋值、切片覆盖、put、where及clip等修改技巧。掌握这些底层逻辑与参数设置,可大幅提升矩阵运算与数据预处理效率。
ndarray数组元素的访问机制
NumPy数组支持类Python列表的切片语法与多维索引,返回的对象仍为ndarray类型。
第1步:掌握切片基础语法
基本格式为arr[start:stop:step]。start与stop分别表示包含起始位置与不包含结束位置的索引,默认为首尾两端;step控制遍历步长,正数从左向右,负数从右向左。负数索引代表从末尾倒序计数。
import numpy as np
nd1 = np.arange(8)
print(nd1[3], nd1[-2]) # 单个索引访问
print(nd1[:3], nd1[2:4]) # 省略start或stop自动填充边界
print(nd1[::-2]) # 步长为-2反向跳跃选取
# 输出: 3 6
# 输出: [0 1 2] [2 3]
# 输出: [7 5 3 1]
第2步:二维/多维数组索引定位
使用逗号分隔维度:arr[行轴, 列轴]。任一维度均可独立使用切片或列表获取多行/多列。若省略某轴索引并使用冒号:,则选中该轴全部数据。
nd2 = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(nd2[1, 2]) # 单元素:第2行第3列
print(nd2[:, 1]) # 整列:所有行的第2列
print(nd2[[0, 2], [0, 2]]) # 花式索引:提取(0,0)与(2,2)
# 输出: 6
# 输出: [2 5 8]
# 输出: [1 9]
ndarray数组元素的增加操作
NumPy数组创建后尺寸固定,添加元素通常会分配新内存并返回新数组。操作时需严格核对输入数据的形状(shape)与目标轴(axis)是否兼容。
第1步:尾部追加与任意位置插入
np.append()仅在末尾拼接,要求values除目标轴外维度与arr一致。np.insert()可在指定位置插入值,obj参数控制插入索引点。
arr = np.array([[1, 2], [3, 4]])
vals = [[5, 6]]
new_append = np.append(arr, vals, axis=0) # 沿行追加
print(new_append.shape)
new_insert = np.insert(arr, 1, vals, axis=0) # 在第2行位置插入
print(new_insert)
# 输出: (3, 2)
# 输出: [[1 2] [5 6] [3 4]]
第2步:多数组合并拼接
np.concatenate()用于元组内的数组序列合并,二维及以上需显式声明axis。np.hstack()与np.vstack()是垂直/水平拼接的便捷别名,对一维数组行为等同concatenate。
a1 = np.array([1, 2])
a2 = np.array([3, 4])
print(np.concatenate((a1, a2))) # 一维拼接无需axis
b1 = np.array([[1], [2]])
b2 = np.array([[5]])
print(np.hstack((b1, b2))) # 水平扩展列
print(np.vstack((b1, b2))) # 垂直扩展行
# 输出: [1 2 3 4]
# 输出: [[1 5] [2 5]]
# 输出: [[1] [2] [5]]
ndarray数组元素的删除操作
删除同样生成新数组。可通过绝对索引剔除特定行列,或使用条件表达式构建布尔掩码进行过滤。
第1步:按索引移除行列
np.delete(arr, obj, axis=None)中,obj接收标量或多维索引列表。二维数组删除行或列时必须指定axis=0或axis=1。
data = np.arange(1, 10).reshape(3, 3)
print(np.delete(data, 1, axis=0)) # 删除第2行
print(np.delete(data, [0, 2], axis=1)) # 删除第1列和第3列
# 输出: [[4 5 6] [7 8 9]]
# 输出: [[2] [5] [8]]
第2步:条件过滤与去重
利用比较运算符生成布尔数组作为索引,可筛选满足条件的子集。np.unique()将返回去重且升序排列后的新数组。
nums = np.array([1, 2, 2, 4, 4, 4, 7])
mask = (nums > 2) & (nums < 6)
filtered = nums[mask]
unique_nums = np.unique(nums)
print(filtered)
print(unique_nums)
# 输出: [4 4 4]
# 输出: [1 2 4 7]
ndarray数组元素的修改操作
修改分为原地覆盖与新数组生成两类。直接索引、切片赋值与布尔掩码属于原地修改;np.put与np.where根据用法决定是否返回新对象。
第1步:直接索引与切片覆盖
通过方括号定位单元素或多元素区间,右侧赋值需保证广播兼容。修改标量会填充至整个切片区域。
m = np.ones((3, 3))
m[0, 1] = 9.9 # 单点修改
m[1:, :] = 0 # 切片整块重置
print(m)
# 输出: [[1. 9.9 1. ]
[0. 0. 0. ]
[0. 0. 0. ]]
第2步:布尔掩码批量替换
将条件表达式置于索引中,可直接定位满足阈值的元素并赋值。注意参与逻辑运算的数组dtype须支持浮点型(如需赋值为NaN)。
v = np.array([1, -2, 3, -4, 5])
v[v < 0] = 0 # 负数清零
v[(v > 1) & (v < 5)] = 2 # 区间覆盖
print(v)
# 输出: [1 0 2 0 5]
第3步:按位赋值与条件三元替换
np.put(a, ind, v)按传入索引列表直接将对应位置改写为v中的值,属于原地操作。np.where(cond, x, y)充当三维三元运算符,符合条件处取x,否则取y。
arr = np.zeros(5, dtype=int)
np.put(arr, [0, 2, 4], [10, 30, 50]) # 原地写回
scores = np.array([85, 40, 92, 55])
status = np.where(scores >= 60, "及格", "挂科")
print(arr)
print(status)
# 输出: [10 0 30 0 50]
# 输出: ['及格' '挂科' '及格' '挂科']
第4步:数值范围裁剪
np.clip(arr, a_min, a_max, out=None)将超出范围的值强制截断至边界。提供out参数时可避免额外内存分配,直接在原数组上生效。
raw = np.array([-2, 3, 7, 12])
cleaned = np.clip(raw, 0, 10, out=raw)
print(cleaned)
# 输出: [0 3 7 10]
操作注意事项与排错建议
- 返回值机制:除直接索引赋值、
np.put及部分带out参数的函数外,绝大多数增删操作均返回新数组,原变量不会被自动覆写。 - 形状对齐:
append与insert要求待拼/插数据的维度与目标轴完全吻合,缺失维度会导致ValueError,建议使用np.expand_dims或转置提前对齐。 - NaN赋值限制:向整数型数组写入
np.nan会被静默转换为2147483647(或平台最大整数值),修改前务必调用astype(float)转换数据类型。
以上就是Python NumPy数组访问与增删改查的详细内容,更多关于NumPy矩阵运算与数据预处理资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













