NumPy 入门:掌握 Python 数据处理的基础能力

发布时间:2026/10/4 20:08:13
NumPy 入门:掌握 Python 数据处理的基础能力 摘要NumPy 是 Python 数据分析生态的重要基础库提供高效的多维数组、向量化运算、广播机制、索引切片和线性代数能力。pandas、SciPy、scikit-learn 等工具都不同程度地建立在 NumPy 的数组思想之上。本文从ndarray开始介绍数组创建、形状、数据类型、索引、切片、广播和聚合运算并通过一个销售数据示例说明如何使用 NumPy 替代低效的 Python 循环。一、背景与问题Python 原生列表使用方便但在大规模数值计算中存在几个问题每个元素都是独立的 Python 对象内存开销较大。循环由 Python 解释器执行计算速度较慢。多维数据需要手动维护嵌套列表结构。缺少统一的向量化运算和矩阵操作。例如计算一百万个数的平方如果逐个使用 Python 循环代码直观但执行效率有限。NumPy 将同类型数据组织成连续的数组并把大量运算交给底层实现完成。Python 列表 └─ 元素逐个处理灵活但循环开销较高 NumPy ndarray └─ 同类型连续数据适合批量数值运算NumPy 并不是要替代所有 Python 数据结构。它更适合处理规则的数值数组复杂的异构业务对象仍然适合使用列表、字典或 DataFrame。二、核心概念1. ndarrayndarray是 NumPy 的核心对象表示一个固定数据类型的多维数组。它主要包含属性含义ndim数组维度数量shape每个维度的长度size元素总数dtype元素数据类型itemsize单个元素占用的字节数二维数组通常可以理解为表格三维数组可以理解为多张表格组成的数据块。2. 形状与轴对于形状为(3, 4)的数组第一个轴有 3 行。第二个轴有 4 列。总元素数量为3 * 4 12。在 NumPy 中axis0通常表示沿行方向聚合即对每一列计算axis1通常表示沿列方向聚合即对每一行计算。3. 数据类型常见数据类型包括int32、int64整数。float32、float64浮点数。bool布尔值。str_字符串。明确的数据类型有助于减少内存占用和避免隐式转换。金融金额、计数和比例等数据应根据业务精度选择合适的表示方式。4. 向量化运算向量化是指直接对数组执行批量操作importnumpyasnp pricesnp.array([10,20,30])discountedprices*0.9这里不需要手动编写for循环数组中的每个元素都会参与乘法运算。5. 广播广播允许形状不同但兼容的数组进行运算importnumpyasnp salesnp.array([[100,200,300],[120,180,260],])discountnp.array([0.9,0.8,0.95])resultsales*discountdiscount会沿着行方向扩展分别作用于三列数据。广播可以减少数据复制但使用前必须理解形状规则。三、工作原理1. 数组存储NumPy 数组通常保存同一种数据类型的元素并通过连续或规则的内存布局组织数据。相较于 Python 对象列表这种布局更适合底层批量计算和缓存访问。数组运算 → 检查形状和 dtype → 应用广播规则 → 调用底层向量化实现 → 返回新数组或写入目标数组并不是所有 NumPy 操作都会创建新数组。合理使用原地操作和输出参数有助于控制大数组的内存占用。2. 索引与视图切片通常可能返回原数组的视图而不是独立副本importnumpyasnp valuesnp.array([10,20,30,40])partvalues[1:3]part[0]999print(values)# [ 10 999 30 40]如果不希望修改原数组可以显式调用.copy()。这是处理数据时容易忽略的引用关系。3. 聚合计算聚合函数可以针对整个数组或指定轴计算importnumpyasnp matrixnp.array([[10,20,30],[40,50,60],])print(matrix.sum())print(matrix.sum(axis0))print(matrix.mean(axis1))理解轴的方向是后续进行分组、矩阵计算和批量特征处理的基础。四、实战示例1. 安装 NumPypython-m pip install numpy建议在项目虚拟环境中安装并将版本写入依赖文件python-m pip freeze requirements.txt2. 创建销售数据数组importnumpyasnp salesnp.array([[1200,3,400],[800,2,400],[1560,4,390],[620,1,620],],dtypenp.float64,)print(维度:,sales.ndim)print(形状:,sales.shape)print(元素数量:,sales.size)print(类型:,sales.dtype)假设每一行表示一笔订单三列依次表示销售金额、商品数量和平均单价。3. 计算统计指标total_amountsales[:,0].sum()average_amountsales[:,0].mean()max_amountsales[:,0].max()print(总金额:,total_amount)print(平均订单金额:,average_amount)print(最大订单金额:,max_amount)sales[:, 0]表示选取所有行的第一列。使用切片后可以直接对整列进行聚合。4. 条件筛选high_value_orderssales[sales[:,0]1000]print(high_value_orders)布尔数组可以作为索引。条件表达式会生成与原数组第一维长度相同的布尔结果masksales[:,0]1000print(mask)5. 向量化计算折扣discount_ratesnp.array([0.9,0.95,0.85,1.0])final_amountsales[:,0]*discount_ratesprint(final_amount)实际项目中应检查两个数组长度是否匹配。如果数据来自不同来源先完成订单 ID 对齐不能仅依赖位置相乘。6. 使用where处理条件amountsales[:,0]labelsnp.where(amount1000,高价值,普通)print(labels)np.where适合表达简单的条件映射。条件很多时应使用更清晰的函数或交给 pandas 的分类逻辑处理。7. 形状变换valuesnp.arange(12)matrixvalues.reshape(3,4)transposedmatrix.Tprint(matrix)print(transposed.shape)reshape要求变换前后元素总数一致。reshape返回的结果可能与原数组共享内存修改前要确认是否需要复制。8. 缺失值处理浮点数组可以使用np.nan表示缺失值valuesnp.array([10.0,20.0,np.nan,40.0])print(np.mean(values))# nanprint(np.nanmean(values))# 忽略 nan 后计算print(np.isnan(values))NumPy 的缺失值能力较基础复杂表格中的缺失值处理通常交给 pandas。9. 保存和读取数组np.save(data/sales.npy,sales)loadednp.load(data/sales.npy)print(np.array_equal(sales,loaded)).npy适合保存 NumPy 数组的类型和形状需要跨语言交换或人工查看时可以考虑 CSV、Parquet 等格式。五、常见问题与实践建议1. 为什么向量化不一定总是更快如果数组很小创建数组和函数调用的开销可能抵消收益。向量化更适合中大规模、规则的数值计算实际项目应通过基准测试验证。2.*和矩阵乘法有什么区别*表示逐元素相乘表示矩阵乘法importnumpyasnp anp.array([[1,2],[3,4]])bnp.array([[5,6],[7,8]])print(a*b)print(a b)不要因为两个数组都是二维就默认*表示矩阵运算。3. 为什么整数数组除法后变成浮点数普通除法可能产生小数因此 NumPy 会返回浮点结果。涉及金额和比例时应明确检查结果类型和精度要求。4. 如何减少大数组内存可以从以下方向入手选择合适的dtype。分块读取和处理。避免不必要的复制。使用原地运算或out参数。及时释放不再使用的中间数组。但不要为了节省内存随意把高精度数据降级先确认业务误差范围。5. 什么时候直接使用 pandas如果数据包含列名、混合类型、日期、分类字段和缺失值pandas 的 DataFrame 更适合。NumPy 主要承担数值数组和底层批量计算。六、进阶思考1. 使用随机数生成可复现实验rngnp.random.default_rng(42)samplesrng.normal(loc100,scale15,size1000)print(samples.mean())固定随机种子有助于复现实验结果。生产模拟任务还应记录随机数算法和参数。2. 批量计算与内存峰值连续创建多个大型临时数组可能导致内存峰值远高于单个数组大小。对于大规模数据可以分块计算读取一块数据 → 计算局部统计 → 累加结果 → 释放当前块 → 处理下一块3. NumPy 与 pandas 的协作可以使用.to_numpy()获取 DataFrame 的底层数组也可以用pd.DataFrame(array)把数组包装成带标签的数据表。转换时要注意索引和列名不会自动保留。4. 从数组计算走向科学计算NumPy 还提供线性代数、随机采样、傅里叶变换等能力。更复杂的优化、统计和科学计算通常会继续使用 SciPy、scikit-learn 或专用领域库。结论NumPy 的核心是ndarray、形状、轴、数据类型、索引切片、广播和向量化运算。掌握这些概念后可以用更少的代码完成批量数值计算并为 pandas、机器学习和科学计算打下基础。下一篇将进入 pandas 的核心数据结构重点理解 Series 与 DataFrame 的索引、列、类型和基本操作。参考资料NumPy 官方文档https://numpy.org/doc/NumPy 用户指南https://numpy.org/doc/stable/user/Python 官方文档https://docs.python.org/3/