ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

[人工智能]Python05:NumPy 数组创建

[人工智能]Python05:NumPy 数组创建 NumPy数组创建构造可靠数组的详细实践指南1. 为什么数组创建很重要数组创建是大多数 NumPy 程序的第一个设计决策。构造函数会确定数组的形状、数据类型、内存布局、初始值以及后续数值代码所依赖的假设。清晰的创建策略可以减少对象数组、整数运算精度不足、空数组被误认为全零数组等隐蔽问题。核心概念可以把 ndarray 理解为“数据 元数据”数值、shape、dtype、strides 和内存所有权。创建数组时这些属性通常已经被确定。图1二维NumPy数组中的形状与从零开始的索引。创建前的五个问题结果应该是什么形状例如可以明确写成 (batch, features)。初始值是什么是零、全一、常量、序列还是由某个规则计算得到应该使用什么 dtype需要同时考虑范围、精度、内存和下游 API。结果应该与原对象共享内存还是必须创建独立副本后续是否需要广播、线性代数、文件存储或连续内存常见目标与构造方式目标推荐构造函数关键说明已知形状并初始化为零np.zeros(shape, dtype...)安全且确定已知形状并填充常量np.full(shape, value)也可以处理字符串和对象已有数据np.array 或 np.asarray明确控制 copy 与 dtype等间隔采样np.linspace指定样本数量固定步长的整数序列np.arange通常不包含 stop浮点步长需谨慎2. 基本构造函数NumPy 的构造函数既表达语义也能够高效完成初始化。最常用的函数可以直接说明初始化策略。只要目标能够由形状、序列或向量化表达式描述就应优先使用这些函数而不是编写嵌套 Python 循环。图2常见NumPy创建函数的概念用途。zeros、ones、full 与 emptyimport numpy as npzeros np.zeros((2, 3), dtypenp.float64)ones np.ones((2, 3), dtypenp.int32)constant np.full((2, 3), 7.5, dtypenp.float32)empty np.empty((2, 3), dtypenp.float64) # 内容未初始化np.empty 只分配指定大小的存储空间不会写入有意义的初始值。在紧密的数值内核中如果每个元素都会立刻被覆盖它可以减少一次初始化写入但在读取之前必须确保所有元素都已赋值。如果更重视安全性和可读性应使用 zeros 或 full。安全规则empty 数组不是全零数组。除非已经赋值否则必须把其中的每一个元素都视为未定义。单位矩阵、对角矩阵与三角结构identity np.eye(4, dtypenp.float64)diagonal np.diag([10, 20, 30])upper np.triu(np.ones((4, 4), dtypeint))lower np.tril(np.ones((4, 4), dtypeint))函数示例结果典型用途np.eye(3)3 × 3 单位矩阵线性代数与测试np.diag(v)对角线上放置数值对角算子np.triu(A)上三角部分三角系统np.tril(A)下三角部分因果或三角结构3. 序列与数值网格序列构造函数广泛用于仿真、绘图、离散化和测试数据。用“指定步长”与用“指定数量”看起来只是参数不同但表达的业务含义并不相同。应选择能准确表达应用不变量的函数。图3arange固定步长linspace固定样本数量。arange 与 linspace 的区别steps np.arange(0, 1, 0.2) # 以步长为中心samples np.linspace(0, 1, 6) # 以数量为中心默认包含终点log_samples np.logspace(0, 3, 5) # 从 10^0 到 10^3整数索引、计数器以及步长明确的场景适合使用 arange。绘图区间、插值网格和需要确定样本数量的数值方法适合使用 linspace。坐标需要在对数尺度上均匀分布时使用 logspace。涉及浮点端点时应检查实际生成的值不要假设十进制步长能够精确表示。网格与坐标场图4坐标网格可以对二元函数进行向量化计算。x np.linspace(-2, 2, 100)y np.linspace(-2, 2, 80)xx, yy np.meshgrid(x, y, indexingxy)z np.sin(xx) * np.cos(yy)assert z.shape (80, 100)meshgrid 会把一维坐标向量变成坐标矩阵。对于可复用代码建议明确写出 indexing 参数xy 适合笛卡尔绘图ij 更接近矩阵索引顺序。对于很大的网格可以考虑 np.ix_通过可广播的坐标视图减少完整矩阵的物化。4. 从已有数据创建数组当数据已经存在时关键问题是 NumPy 应该复制数据、共享视图还是把输入转换成数组。array、asarray、asanyarray 和 copy 看起来相似但它们对所有权、复制和子类的意图不同。array、asarray 与 copyvalues [1, 2, 3]a np.array(values, dtypenp.float64) # 新 ndarrayb np.asarray(values, dtypenp.float64) # 转换 array-likec np.array(a, copyFalse) # 可能复用 ad a.copy() # 独立数据函数默认意图适用场景np.array按指定规则创建 ndarray需要明确的 dtype 和复制行为np.asarray尽量避免不必要的复制接收 array-like 输入的函数np.asanyarray保留 ndarray 子类需要支持数组子类的库代码ndarray.copy创建独立数据需要安全修改工作副本从可迭代对象、函数和记录创建values np.fromiter((n * n for n in range(5)), dtypenp.int64)rows np.fromfunction(lambda i, j: i 10 * j, (3, 4), dtypeint)records np.array([(1, 2.5), (2, 4.0)],dtype[(id, i4), (score, f8)])当只遍历一次且 dtype 已知时fromiter 适合把迭代器转为数组。fromfunction 会向函数传入坐标数组而不是为每个元素单独调用函数。结构化 dtype 可以创建带名称字段的紧凑记录但在普通数值计算中同质数组通常更简单。5. dtype、精度与内存dtype 是数组契约的一部分。它会影响可表示的数值范围、算术行为、内存占用、互操作性以及部分场景下的性能。涉及复现和文件兼容时不要完全依赖平台默认 dtype。图5常见NumPy dtype的单元素典型字节数。如何选择 dtype数据可作为起点的dtype原因较小的非负计数np.uint8/uint16在范围允许时节省空间一般整数 IDnp.int64范围宽且生态常见传感器或机器学习特征np.float32内存更小并适合加速器高精度 CPU 计算np.float64生态支持广泛标签或类别字符串/对象或整数编码根据下游 API 选择a np.zeros(1_000_000, dtypenp.float32)b np.zeros(1_000_000, dtypenp.float64)print(a.nbytes, b.nbytes) # 标准 dtype 下通常为 4000000 和 8000000类型转换应当是有意的。缩窄类型可能损失范围或精度转为整数会截断小数。比较浮点计算结果时应根据问题规模选择 np.isclose 或 np.allclose 以及合适的容差。可复现性在数据契约、测试和序列化元数据中记录 shape 与 dtype。数值相同但 dtype 不同的数组后续运算可能产生不同结果。6. 合并与重塑创建出的数组实际工作流很少只调用一次构造函数。通常还需要拼接数据块、增加维度或者重塑数组以适应下游算法。如果在每一步旁边写出预期 shape就更容易发现轴选择错误。图6vstack与hstack沿已有轴拼接stack会创建新轴。a np.array([[1, 2], [3, 4]])b np.array([[5, 6], [7, 8]])vertical np.vstack((a, b)) # (4, 2)horizontal np.hstack((a, b)) # (2, 4)new_axis np.stack((a, b), axis0) # (2, 2, 2)block np.block([[a, b], [b, a]]) # (4, 4)保持形状与改变形状的操作操作轴的行为常见错误concatenate沿已有轴拼接除目标轴外的维度不一致stack增加一个新轴以为二维输入仍会得到二维结果expand_dims增加长度为 1 的轴增加到错误一侧导致广播错误reshape尽可能以视图改变形状忽略元素数量必须相等squeeze删除长度为 1 的轴输入形状变化时秩意外变化以形状为中心的工作流先用 .shape 和 .ndim 检查每个输入。选择真正要扩展的轴行、列、批次还是通道。复杂创建后立即断言预期形状。重复使用的形状约定应封装为带文档的辅助函数。7. 面向生产的数组创建模式可靠的数组创建层应当尽早拒绝非法输入并明确记录广播或 dtype 强制转换中可能隐藏的假设。下面的模式足够小适合放入工具模块同时也便于代码审查。def make_feature_matrix(rows, features, dtypenp.float32):if rows 0 or features 0:raise ValueError(rows and features must be nonnegative)result np.zeros((rows, features), dtypedtype)assert result.ndim 2assert result.shape (rows, features)return result在创建大数组之前验证维度。把 dtype 暴露为参数不要让临时值默默决定最终类型。测试中使用确定性的构造函数随机生成应明确使用带种子的 Generator。大规模规则结构优先使用向量化构造而不是 Python 循环。在文档中说明函数返回的是视图、副本还是新分配的存储。检查清单检查项要问的问题Shape每个轴的含义是否已经说明Dtypedtype 是否覆盖预期的范围和精度初始化是否可能在赋值前读取某个元素所有权调用者是否可能通过共享视图意外修改源数据规模最大输入下的内存分配是否可接受测试是否断言 shape、dtype 和代表性数值
返回列表