news 2026/3/10 1:22:36

Numpy入门详细教程:核心用法一文掌握

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Numpy入门详细教程:核心用法一文掌握

Numpy核心用法精讲:从入门到实战的全面掌握

在数据科学的世界里,Python之所以能成为主流语言,离不开背后强大的数值计算生态。而在这套体系中,Numpy 是真正的基石——它不仅为 Pandas 提供了底层支持,更是 Scikit-learn、PyTorch 乃至 TensorFlow 中张量运算的灵感来源。

它的核心优势在于:以接近C语言的速度执行向量化操作。这意味着你可以像写公式一样处理成千上万的数据点,而无需陷入低效的for循环泥潭。本文将带你深入理解 Numpy 的设计哲学与关键机制,通过真实可运行的代码示例,构建一套完整的使用直觉。


ndarray:多维数组的本质是什么?

Numpy 的灵魂是ndarray(n-dimensional array),一个固定类型、连续内存存储的同构数据容器。这与 Python 原生列表有着本质区别:

import numpy as np # 列表可以混合类型 py_list = [1, "hello", 3.14] # 数组必须统一类型,自动推断或强制转换 arr = np.array([1, 2, 3]) # int64 arr_float = np.array([1, 2, 3], dtype=np.float32)

由于所有元素类型一致且内存连续,CPU 缓存可以高效预取数据,配合底层用 C 实现的通用函数(ufunc),实现了远超原生 Python 的性能。

什么是 ufunc?
它是一类“逐元素”操作函数,比如+,-,np.sin,>等。它们不需要你写循环,就能直接作用在整个数组上:

python arr = np.array([1, 2, 3]) result = np.sin(arr) # 自动对每个元素求 sin

这些操作在 C 层面完成隐式循环,避免了解释器开销,是 Numpy 高性能的核心秘密之一。

此外,ufunc还自带四个高级聚合方法,极大增强了表达能力:

方法说明
.reduce()沿轴累积(如add.reduce相当于 sum)
.accumulate()返回累积过程(如前缀和)
.outer()计算两个数组的外积
.reduceat()分段聚合(较少用)

实际中最常用的是前两个:

np.add.reduce([1, 2, 3, 4]) # → 10 np.multiply.accumulate([1, 2, 3, 4]) # → [1, 2, 6, 24]

这种“把运算当成对象来调用”的方式,虽然初看有点奇怪,但一旦熟悉后会发现其逻辑非常清晰。


如何创建数组?五种实用场景全覆盖

从 Python 数据结构转换

最直观的方式是从列表或元组生成数组:

np.array([1, 2, 3]) # 一维 np.array([[1, 2], [3, 4]]) # 二维矩阵 np.array((1, 2, 3), dtype='f4') # 指定 float32 类型

注意:一旦创建,数组大小和类型就基本固定(除非使用resize),这是为了保证内存效率。

快速构造特定结构

当你需要初始化某种模式的数组时,Numpy 提供了大量便捷函数:

np.zeros((2, 3)) # 全零 np.ones((2, 2)) # 全一 np.full((2, 2), 7) # 填充指定值 np.eye(3) # 单位矩阵 np.empty((2, 2)) # 未初始化(速度快,值随机)

其中empty特别适合高性能场景——如果你马上要覆盖全部数据,就没必要花时间清零。

生成等差/等比序列

两种常用方式:

np.arange(0, 10, 2) # [0, 2, 4, 6, 8] ← 不包含终点 np.linspace(0, 1, 5) # [0.0, 0.25, 0.5, 0.75, 1.0] ← 默认含终点

一个小细节:arange更像 Python 的range,适用于整数步长;而linspace按数量划分区间,更适合浮点运算。

从文件加载

支持多种格式读取:

np.load('data.npy') # 二进制保存的数组 np.loadtxt('data.txt') # 文本数据 np.genfromtxt('data.csv', delimiter=',') # CSV 文件(更健壮)

这对于实验数据复现、模型初始化非常有用。

随机数生成(详见后续章节)

Numpy 的random模块提供了丰富的分布采样工具,常用于模拟、初始化权重等任务。


数组的“增删改查”:别被名字误导!

Numpy 数组本质上是固定大小的对象,所谓的“修改”其实都是返回新数组的操作。

添加元素

a = np.array([[1, 2], [3, 4]]) b = np.append(a, [[5, 6]], axis=0) # 在末尾追加一行 c = np.insert(a, 1, [9, 9], axis=0) # 在第1行插入

⚠️ 注意:这些操作不会改变原始数组a,而是返回副本。频繁拼接会导致性能下降,建议提前规划好形状。

删除元素

d = np.delete(b, 2, axis=0) # 删除第3行

同样返回新数组。这类操作应尽量减少使用,尤其在循环中。


形状变换:灵活重塑你的数据

很多时候我们需要调整数组维度而不改变内容,这就是“变形”。

reshape:重新排列维度

arr = np.arange(6) reshaped = arr.reshape(2, 3)

支持-1推断维度:

arr.reshape(3, -1) # 自动算出 (3, 2)

只要总元素数不变即可。

resize:真正改变大小

不同于reshaperesize可以修改总数:

arr.resize(3, 3) # 原地修改,不足补0,超出截断

但它只能用于拥有独立内存的数组,不能用于视图(view)。

展平操作:ravel vs flatten

两者都能展平数组,但行为不同:

flat_view = arr.ravel() # 返回视图,可能共享内存 flat_copy = arr.flatten() # 总是返回副本

因此,修改ravel结果可能影响原数组,需谨慎。

转置与重排轴

mat.T # 转置 high_dim.transpose(2, 0, 1) # 三维数组重排序

对于高维数据(如图像(H, W, C)),转置可用于通道变换。

复制数组:tile vs repeat

np.tile([1, 2], 3) # [1,2,1,2,1,2] ← 整体重复 np.repeat([1, 2], 2) # [1,1,2,2] ← 元素级重复

用途不同:前者适合构造周期性结构,后者适合数据扩充。


拼接与切分:组合与拆解的艺术

拼接:concatenate 与 stack 系列

np.concatenate([a, b], axis=0) # 沿轴连接 np.vstack([a, b]) # 垂直堆叠(等价于 axis=0) np.hstack([a, b]) # 水平堆叠(等价于 axis=1)

stack会在新增维度上堆叠:

np.stack([a, b], axis=0) # 输出 shape: (2, ...) ← 多一维

特别地,column_stack对一维数组会自动视为列向量。

魔法语法:r_ 和 c_

非函数,属于索引技巧,写起来极简:

from numpy import r_, c_ r_[1:4, 0, 4] # [1,2,3,0,4] c_[[1,2,3]] # 列向量 [[1],[2],[3]]

适合快速原型开发。

切分:split 与 array_split

x = np.arange(9).reshape(3, 3) np.hsplit(x, 3) # 按列切分 np.vsplit(x, 3) # 按行切分 np.array_split(x, 4) # 允许不均等分割(推荐)

相比splitarray_split更鲁棒,即使无法整除也能工作。


统计与排序:一键获取数据洞察

Numpy 内置了几乎所有常用的统计函数,且都支持axis参数控制聚合方向:

data = np.array([[3, 1], [2, 4]]) data.max(axis=0) # 每列最大值 → [3, 4] data.argmax(axis=1) # 每行最大值索引 → [0, 1] np.sort(data, axis=0) # 按列排序 np.cumsum(data) # 累计求和

常见方法包括:

  • 极值:max/min,argmax/argmin
  • 均值相关:mean,std,var
  • 求和:sum,cumsum
  • 排序:sort(返回新数组)、argsort(返回索引)

🔍 若axis=None(默认),则对整个数组展开后统计。


视图 vs 拷贝:内存共享的陷阱与技巧

这是最容易出错的部分。三种赋值方式的行为完全不同:

a = np.array([1, 2, 3]) # 引用:完全共享 b = a b[0] = 99 print(a) # [99, 2, 3] ← a 被意外修改! # 浅拷贝:数据共享,形状可变 c = a.view() c.shape = (1, 3) # 深拷贝:完全独立 d = a.copy() d[0] = 100 print(a) # 仍为 [99, 2, 3]

总结如下:

操作是否共享内存说明
b = a✅ 是完全等价
b = a.view()✅ 是可变形状,共用数据
b = a.copy()❌ 否独立副本

因此,在做数据预处理时,务必确认是否需要深拷贝,否则可能污染原始数据。


升维技巧与特殊常量

Numpy 定义了一些实用常量:

np.pi # π ≈ 3.14159 np.e # e ≈ 2.71828 np.inf # 正无穷 np.nan # 非数字(NaN)

还有一个神器:np.newaxis(等价于None),用于升维:

vec = np.array([1, 2, 3]) col_vec = vec[:, np.newaxis] # (3,) → (3, 1) row_vec = vec[np.newaxis, :] # (3,) → (1, 3)

这个技巧在广播中极为重要,能让一维数组参与更高维运算。


随机数模块:模拟与初始化的利器

np.random是生成随机数的核心工具包:

np.random.seed(42) # 设置种子,确保结果可复现 # 常见分布 np.random.rand(3, 3) # [0,1) 均匀分布 np.random.randn(3) # 标准正态分布 np.random.randint(1, 10, size=5) # 整数随机 np.random.normal(100, 15, 1000) # 智商分布模拟

还有序列操作:

idx = np.arange(10) shuffled = np.random.permutation(idx) # 返回打乱的新数组 np.random.shuffle(idx) # 就地打乱

在机器学习中,常用于打乱训练集顺序,防止批次偏差。


线性代数:科学计算的硬核支撑

np.linalg提供完整的线性代数功能:

A = np.array([[3, 1], [1, 2]]) b = np.array([9, 8]) x = np.linalg.solve(A, b) # 解 Ax = b det_A = np.linalg.det(A) # 行列式 inv_A = np.linalg.inv(A) # 逆矩阵 eig_vals, eig_vecs = np.linalg.eig(A) # 特征分解

常用操作还包括:

方法功能
np.dot(A, B)矩阵乘法(也可用@
np.outer(a,b)外积
np.vdot(a,b)内积(支持复数共轭)

值得一提的是,dotvdot因使用频繁,被提升至顶层命名空间,无需加linalg.前缀。


深度解析:axis 到底怎么理解?

这是初学者最大的困惑点。记住一句话:

“axis=n 表示沿着该轴进行操作,结果中该轴将被压缩消失。”

来看一个二维例子:

[[1, 2], [3, 4]]
  • axis=0:纵向操作(跨行),即“对每列进行统计”
  • axis=1:横向操作(跨列),即“对每行进行统计”
np.sum(arr, axis=0) # → [4, 6] ← 每列相加,行维度消失 np.sum(arr, axis=1) # → [3, 7] ← 每行相加,列维度消失

🧠 记忆口诀:你告诉 Numpy “忽略哪个轴”,它就会在这个方向上聚合

对于三维数组(batch, height, width)

  • axis=0:对 batch 维度聚合(剩下height × width
  • axis=1:对 height 聚合(剩下batch × width

依此类推。


广播机制:Numpy 最强黑科技

广播允许形状不同的数组进行逐元素运算,只要满足以下规则:

从最后一个维度向前比较,每个维度必须相等,或其中一个为 1。

示例分析

✅ 可广播:

A: (3, 1) → 可扩展为 (3, 4) B: (4,) → 先升维为 (1, 4),再扩展为 (3, 4) → 运算合法

❌ 不可广播:

A: (2, 3) B: (3, 2) # 最后一维 3 vs 2,既不等也不为1 → 报错

为什么只能是 1 扩展到 N?因为语义明确:复制。如果是 2 扩展到 6,系统无法判断你是想重复三次还是插值填充。

广播的意义在于:避免显式复制,节省内存和时间。例如将一个偏置向量加到每行数据上,无需手动 tile。


关键要点总结

  • Numpy 是数据科学生态的地基,几乎所有高级库都依赖它。
  • 向量化 + ufunc + 广播是性能飞跃的核心三要素。
  • axis 的本质是“压缩轴”,不是“操作轴”的方向。
  • 区分 view 与 copy,防止因内存共享引发 bug。
  • 合理使用 random 和 linalg,支撑建模与仿真需求。

掌握这些概念后,你会发现 Pandas 的groupby、PyTorch 的tensor都变得顺理成章。Numpy 不仅是一个工具,更是一种思维方式——用数组代替标量,用整体代替局部,这才是现代数据编程的精髓所在。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/8 3:59:48

基于 PLC 的卷扬机控制系统设计

第一章 系统方案规划 本系统以 “安全吊运、精准调速、过载防护” 为核心目标,采用 “PLC 变频器 编码器” 架构,实现工业卷扬机(如矿山提升、建筑吊装)的起升 / 下降控制、速度调节、位置限位及故障保护,适配 5-20 …

作者头像 李华
网站建设 2026/3/8 16:18:21

8个降AI率工具推荐!继续教育人群必备神器

8个降AI率工具推荐!继续教育人群必备神器 AI降重工具:论文写作的得力助手 在继续教育的学习过程中,论文写作是不可避免的重要环节。然而,随着AI技术的广泛应用,许多学生发现自己的论文被检测出较高的AIGC率&#xff0c…

作者头像 李华
网站建设 2026/3/8 21:10:40

安装失败?Open-AutoGLM集成第三方应用的7大痛点与破解方案

第一章:Open-AutoGLM怎么安装其他应用Open-AutoGLM 是一个基于 AutoGLM 架构的开源自动化平台,支持扩展第三方应用以增强其功能。用户可通过插件机制集成外部工具,实现任务自动化、数据处理和模型调用等功能。环境准备 在安装其他应用前&…

作者头像 李华
网站建设 2026/3/3 17:57:37

gbase8s如何操作时间

gbase模式select cast(current year to second - date(2025-01-01) as interval day(9) to day) from dual;select cast(current year to second - date(2025-01-01) as interval second(9) to second) from dual;oracle模式-- 返回两个日期之间的天数差 SELECT DATE 2024-12-3…

作者头像 李华
网站建设 2026/3/4 0:56:23

用Graphpad Prism 8.0绘制Cleveland点图

用 GraphPad Prism 8.0 绘制 Cleveland 点图:无需编程的科研可视化实践 在撰写论文或准备学术报告时,你是否曾为如何清晰呈现多组实验数据而苦恼?柱状图容易误导读者对离散值的理解,箱线图又可能掩盖个体观测点的信息。有没有一种…

作者头像 李华