1. 为什么搞懂numpy比收藏一堆教程更重要先讲个我身边真实到不能再真实的场景。一个刚转行学人工智能的朋友花了两周时间把Python基础语法过了一遍list、dict、for循环用得挺顺然后兴冲冲去学PyTorch结果第一天就被张量运算卡住了。他跑回来问我为什么PyTorch的Tensor这么难用明明Python的list也能做矩阵啊我当时就回了一句list是装数据的篮子numpy的ndarray才是能直接拿来算的算盘。这句话虽然糙但确实是很多人始终没想通的一个坎。说句实在话现在所有主流的深度学习框架——PyTorch、TensorFlow、PaddlePaddle它们的底层数据结构和核心运算逻辑几乎都是基于NumPy的设计思路发展出来的。你把numpy里的ndarray、广播机制、向量化运算这几个概念吃透了再去看那个框架的张量操作基本就是换了个马甲而已。这也是为什么几乎所有人工智能基础课程都会把numpy摆在第零位或者第一位来讲。这篇文章不打算搞那种从入门到精通的假大空标题也不准备写成官方文档的翻译版。我就站在一个实际踩过坑、写过代码、也被numpy版本问题折磨过的从业者角度把大家学numpy时最容易懵的几个知识点掰开揉碎讲清楚。尤其是小白经常卡住的安装配置、ndarray和list的区别、索引取值、广播机制以及为什么numpy比for循环快那么多这些热搜词里反复出现的高频问题全部都会覆盖到。不管你是刚装好Python还没跑通numpy还是正在被布置的头歌numpy基础及取值操作作业折磨又或者是准备转行做数据分析、人工智能方向这篇内容应该能帮你把路由打通。2. numpy装上之后不等于能用环境配置里那些隐秘的坑先把这个最劝退的问题解决掉。热搜词里几乎被numpy安装、ModuleNotFoundError、为什么pycharm有numpy但一直显示没有、numpy版本不匹配这类问题刷屏了我完全理解那种感觉——明明按照教程做了就是跑不起来这时候心态很容易崩。2.1 安装numpy的正确姿势和卡住的原因如果你用的是Anaconda发行版那么大概率numpy已经预装好了打开终端或者Anaconda Prompt输入以下命令验证一下python -c import numpy; print(numpy.__version__)如果能打印出类似1.26.4这样的版本号说明numpy已经可用了直接跳到下一节就行。如果直接报ModuleNotFoundError: No module named numpy那才需要手动安装。手动安装时我建议优先使用pip而不是conda原因后面说。常规命令是pip install numpy但很多人在执行这一步的时候会遇到标题里提到的那个情况——在Installing backend dependencies卡住不动了。这个问题的根源通常不是网络被墙而是pip在构建numpy的依赖setuptools和wheel时尝试从境外PyPI源拉取元数据速度慢到像假死。解决方法是换用国内镜像源例如清华或者阿里云的镜像命令如下pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple如果还是卡我建议先用python -m pip install --upgrade pip把pip本身升级一下然后加一个参数pip install numpy --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple--no-cache-dir的意思是放弃本地缓存强制重新拉取完整包很多时候卡住就是因为本地缓存了半个损坏的包文件pip反复校验不过去。2.2 ModuleNotFoundError的排查链路pycharm的经典骗局这是热搜里最扎心的问题为什么pycharm有numpy库但是一直显示没有我远程帮人排查过好几次这种问题十次里有八次是解释器选错了。pycharm本身是一个IDE它不是Python环境。你装Python的时候可能装了2个不同的解释器比如一个系统自带的/usr/bin/python3一个自己手动装的/usr/local/bin/python3Anaconda又可能往~/.conda/envs里塞了一个虚拟环境。Pycharm里看到的有numpy指的是你正在使用的那个解释器有numpy而终端里python命令指向的可能是另一个完全不同的解释器那里没装numpy所以python -c import numpy就报错了。排查链路我建议按这个顺序走在pycharm的终端Terminal里执行which python看当前这个终端用的Python路径。在pycharm右下角状态栏看当前项目选中的解释器路径。如果两个路径对不上打开Settings → Project → Python Interpreter点击齿轮图标选择Add Interpreter把解释器路径指到你终端里那个which python查出来的路径。如果路径一致还是报错再执行pip list | grep numpy看numpy究竟装没装在这个解释器对应的site-packages里。另外还有个细节很多人会在pycharm里直接点右下角的Install package按钮那个操作虽然方便但经常因为权限问题失败。我个人的习惯是直接用命令行安装然后在pycharm里刷新一下解释器这样出问题更好定位。2.3 版本不匹配的连锁反应numpy版本不匹配这个问题通常在两种情况下爆发。第一种是你用pip install pandas的时候pip自动安装了最新版的numpy 2.x而项目里之前依赖numpy 1.x的旧代码比如某些只适配旧接口的库就开始报错。第二种是你同时用conda和pip混着装包conda把numpy锁在一个版本pip又强行升级导致包管理系统之间的元数据不一致。遇到这种情况我的建议是先定位哪个库需要什么版本比如pandas新版本依赖的是numpy1.22那你把numpy降级到1.26.x基本都能兼容。降级方法如下pip install numpy1.26.4 -i https://pypi.tuna.tsinghua.edu.cn/simple需要特别警惕的是不要轻易把所有库都升到最新版。在人工智能和数据科学这个生态里稳定压倒一切。我见过太多人去追求全依赖最新结果PyTorch跑不起来、matplotlib画图崩了最后花一晚上排查依赖关系得不偿失。2.4 小心伪numpy错误trapz这类属性陷阱热搜里有个挺有意思的词条module numpy has no attribute trapz。这个错误很典型是初学者把函数名放错模块了。trapz梯形法积分这个函数确实存在但它不在numpy里而是在scipy.integrate里面。正确用法是from scipy.integrate import trapz import numpy as np y np.array([1, 2, 3, 4]) x np.array([0, 1, 2, 3]) result trapz(y, x)这个问题背后的逻辑是很多人刚开始学numpy以为它是数学函数大全什么函数都有。其实numpy的核心是数组运算那些需要专门领域的数学函数积分、优化、信号处理应该去scipy找。这个观念转过来之后你以后遇到类似问题就不会蒙了。再科普一个同款陷阱np.median是有的但np.mode众数在旧版本里没有得从scipy.stats里导入。3. ndarray和list的本质区别你的矩阵到底怎么存3.1 定长存储、同质元素与连续内存我们做一个很直观的对比实验。import numpy as np python_list [1, 2, 3, 4, 5] numpy_array np.array([1, 2, 3, 4, 5]) print(python_list[0]) print(numpy_array[0])从表面上来看两者都能取出第一个元素但内部的存储方式完全不同。Python的list里面装的其实是一个个对象引用每个元素都是一个独立的Python对象这些对象在内存里是分散存放的之间靠指针连接在一起。所以list能装不同类型的数据比如[1, hello, 3.14]因为每个元素都是独立的引用。而numpy的ndarray要求所有元素类型相同它把数据存储在一块连续的内存区域里。这样做的好处有两个第一是读取速度极快因为连续内存对CPU缓存友好遍历时不需要跳转到不同地址第二是能做真正的数学运算比如numpy_array * 2会让每个元素都乘2而python_list * 2只会把整个列表重复两遍。再看形状信息。numpy_array.shape会返回(5,)表示这是一个一维数组长度为5。Python list没有这个概念。如果你要用list模拟二维矩阵通常是一个大列表里面嵌套几个小列表访问matrix[0][1]在numpy里则非常直观matrix np.array([[1, 2, 3], [4, 5, 6]]) print(matrix[0, 1]) # 输出2这个matrix[0, 1]的写法用英文逗号分隔维度的索引比[0][1]更清晰也更快——因为[0][1]实际上做了两次索引操作。3.2 为什么不推荐用Python for循环做数值计算很多人刚开始做矩阵运算时第一反应是result [] for i in range(len(a)): result.append(a[i] * 2)这个写法在数据量特别小的时候没什么毛病但一旦数据量到百万、千万级别性能差距就会非常悬殊。原因不只是CPU缓存的问题还有Python本身的解释器开销——每一个循环迭代都要做类型检查、异常处理、对象创建销毁这些都在拖慢速度。而numpy把循环下沉到了C语言层面直接用优化过的C代码处理连续内存里的数据块。所以你应该这样写a np.array([1, 2, 3, 4, 5]) result a * 2这个向量化写法代码量更少可读性更强性能也更好。我在实际项目里用timeit测试过对一千万个元素的数组做乘2运算for循环耗时大约400毫秒numpy向量化只要10毫秒左右差了40倍。当你的数据维度上升之后这个差距会被拉得更夸张。4. numpy基础及取值操作从五类创建方式到花式索引4.1 创建ndarray的五种常用武器学习numpy的取值前提是先学会创建数组。我给初学者总结了一个五件套日常工作里覆盖了80%以上的场景。第一种从列表转换arr1 np.array([[1, 2, 3], [4, 5, 6]])这应该是最直觉的创建方式直接把Python的嵌套列表转成ndarray。注意一点如果嵌套列表里面每一行长度不一样比如np.array([[1, 2, 3], [4, 5]])numpy会自动把它当作一维的对象数组而不是二维数组这样就算创建失败了形状完全不符合预期。所以创建二维数组前先确认内层列表数量一致。第二种全零和全一zeros np.zeros((3, 4)) # 3行4列全是0 ones np.ones((2, 3)) # 2行3列全是1这个用途非常广泛。比如初始化权重矩阵、创建一个占位的累积数组都可以用它。还有一个实用变体是np.eye(4)生成4行4列的单位矩阵对角线是1其余是0。很多数学推导里直接用得到。第三种等差序列arr2 np.arange(0, 10, 2) # 从0到10步长为2输出[0, 2, 4, 6, 8] arr3 np.linspace(0, 10, 5) # 从0到10均匀分成5个数输出[0, 2.5, 5, 7.5, 10]np.arange和内置的range很像但返回的是ndarray步长可以是小数。np.linspace则是均匀分割第五个参数表示生成几个数。在画图时linspace出坐标轴的均匀点非常常用。第四种随机数np.random.seed(42) # 固定随机种子让结果可复现 arr4 np.random.rand(3, 3) # 3x3的均匀分布随机数范围[0,1) arr5 np.random.randn(5) # 5个标准正态分布随机数 arr6 np.random.randint(0, 10, size(2, 3)) # 2x3的整数随机数范围[0,10)很多初学者忽略random.seed的重要性。在调试和复现实验时如果不固定随机种子每次运行的结果都不同你根本没法判断代码改对没有。所以只要遇到用随机数的地方第一行务必先固定种子。第五种从文件加载loaded np.loadtxt(data.txt, delimiter,)如果你的数据是CSV格式用np.loadtxt或者np.genfromtxt读取非常方便。np.loadtxt要求数据规整而genfromtxt能容忍部分缺失值会填NaN。数据分析入门时这两个函数建议都试一试。4.2 一维和二维数组的索引取值我们的目标是搞懂numpy怎么取值这部分直接决定你能不能写完作业。先看一维数组它和list的索引基本一致从0开始负索引从末尾倒数arr np.array([10, 20, 30, 40, 50]) print(arr[0]) # 10 print(arr[-1]) # 50 print(arr[1:4]) # array([20, 30, 40])二维数组的索引稍微绕一点。特别注意arr[行, 列]行和列用逗号隔开行在前列在后mat np.array([[1, 2, 3], [4, 5, 6]]) print(mat.shape) # (2, 3)2行3列 print(mat[1, 1]) # 5第2行第2列 print(mat[0, :]) # 第一行全部array([1, 2, 3]) print(mat[:, 1]) # 第二列全部array([2, 5]) print(mat[1:, :2]) # 第2行开始的所有行第1列到第2列array([[4, 5]])看到冒号:就理解为这一维全部取。这个思维特别关键比如你想提取特征矩阵的某些列做数据分析data[:, [0, 2]]就是取第1列和第3列。4.3 布尔索引与花式索引取值的进阶玩法布尔索引是我个人觉得最实用、也最容易被忽略的技巧。它允许你用条件表达式直接筛选元素scores np.array([65, 80, 92, 58, 73]) passed scores[scores 60] print(passed) # array([65, 80, 92, 73])这里的scores 60会生成一个布尔数组[True, True, True, False, True]然后用这个布尔数组去索引原数组保留下来的就是成绩及格的元素。比for循环遍历if判断简洁太多。再多加一个条件比如找出60到85之间的分数mask (scores 60) (scores 85) print(scores[mask])注意numpy里逻辑与是逻辑或是|不是Python里的and和or。这个小地方踩坑率极高。花式索引则是用整数数组来指定位置indices np.array([0, 2, 4]) print(scores[indices]) # 取出第0、2、4个元素二维数组的花式索引还会多一个坐标配对的逻辑。比如mat[[0, 1], [1, 2]]返回的是array([mat[0,1], mat[1,2]])也就是两个坐标分别取而不是取所有行列的交集。要取所有行列的交集得用np.ix_rows [0, 1] cols [1, 2] submat mat[np.ix_(rows, cols)] print(submat)这个np.ix_的细节很多教材都直接跳过但是自己摸索的时候很容易绕进去。4.4 作业常考的行列式与特殊矩阵误区热搜里有一个很具体的问题python行列式计算不使用numpy。这个需求一看就是某门编程课的作业要求。我的建议是这样真正需要用行列式的时候直接从numpy.linalg模块里调matrix np.array([[1, 2], [3, 4]]) det np.linalg.det(matrix) print(det) # -2.0000000000000004但如果作业明确要求不能使用numpy你只能用纯Python递归展开。对二阶行列式直接写公式ad - bc对三阶以上用拉普拉斯展开。这种题目考的是编程基本功不是数学计算能力所以不用慌把思路理清楚就能写。先确认作业的要求是不准用numpy计算还是不准import numpy。顺带一提很多人在改造数学公式时会把矩阵乘法和元素乘混淆。numpy里A * B # 逐元素相乘Hadamard积 np.dot(A, B) # 矩阵乘法 A B # 矩阵乘法和dot等价如果你学过线性代数应该清楚矩阵乘法要求A的列数等于B的行数结果形状是(A的行数, B的列数)。这里我建议初学者直接养成用的习惯代码更简洁也和深度学习框架里张量乘法的写法一致。4.5 三维数组乘法理解维度扩张热搜里出现numpy三维数组相乘这其实是很多人从二维过渡到三维时的一个坎。三维数组的形状写成(a, b, c)前面是批次batch后面是具体矩阵维度。比如形状为(3, 2, 4)的数组可以理解为3个2x4的矩阵叠在一起。两个三维数组做乘法时numpy要求最后两维满足矩阵乘法规则前面的批次维度必须一致a np.random.rand(3, 2, 4) # 3个 2x4 矩阵 b np.random.rand(3, 4, 5) # 3个 4x5 矩阵 c a b # 结果形状(3, 2, 5)这相当于同时对3个矩阵做了乘法。在深度学习中批处理图片数据时输入形状往往是(batch_size, channels, height, width)你要对每个样本做矩阵运算这种三维甚至四维的操作就特别常见。还有一种情况是(3, 1, 4)和(3, 4, 5)做乘法numpy会先把第二维广播扩展再逐对相乘这就是下一节要说的广播机制。5. 广播机制numpy里无形之间帮你对齐维度5.1 三条规则记熟了就是半个numpy高手广播Broadcasting是numpy里概念上最简单、实际推理时最容易出错的机制。它解决的核心问题是两个形状不完全一样的数组怎么直接做运算我举一个生活化的例子。假设你在统计每周的销售额得到了一个7天的数组daily_sales形状(7,)另外还有一个基准线baseline是一个数值100。你想看每天超出基准多少在大多数编程语言里你得写个循环但在numpy里diff daily_sales - 100这里100被广播成一个长度为7的数组每个元素都是100然后逐元素相减。numpy处理得非常高效它并没有真的创建一个全是100的数组而是在底层虚拟地扩展了它。再复杂一点的情况比如一个形状(3, 1)的数组和一个形状(1, 4)的数组相加numpy会怎么处理答案是它会把第一数组扩展成(3, 4)复制列把第二数组也扩展成(3, 4)复制行最后逐元素相加。广播机制的三条规则如下建议收藏如果两个数组的维度数不同维度数较少的数组形状前面补1直到维度数一致。从最后一个维度开始比较如果两个维度相等继续看下一个维度。如果某个维度其中一个值为1另一个不为1那就把值为1的那个维度扩展成另一个值如果两个值都不相等且都不为1直接报错。a np.array([[1], [2], [3]]) # 形状 (3, 1) b np.array([10, 20, 30, 40]) # 形状 (4,) # 第一步b补1变成 (1, 4) # 第二步从后往前比较维度1和4不相等a的维度是1可以扩展最终结果 (3, 4) print(a b) # 输出 # [[11 21 31 41] # [12 22 32 42] # [13 23 33 43]]5.2 广播最常见的翻车现场初学者最容易翻车的点是搞不清形状(3,)和形状(3, 1)的区别。形状(3,)是一维数组只有一行上的3个元素形状(3,1)是二维数组3行1列。它们和另一个形状(1,4)的数组相加时结果完全不同。a1 np.array([1, 2, 3]) # (3,) b np.array([[10, 20, 30, 40]]) # (1,4) print(a1 b) # 报错还是形状(3,4) a2 np.array([[1], [2], [3]]) # (3,1) print(a2 b) # 形状(3,4)成功第一个会报错因为(3,)和(1,4)从末尾比较3和4不相等且没有1可以扩展。第二个成功因为(3,1)和(1,4)各自都有1可以扩展。解决方法是给一维数组补一个维度用a1[:, None]或者a1.reshape(-1, 1)。5.3 广播的实际应用归一化和外积广播机制在数据预处理里太常用了。比如你要对一个二维矩阵的每一列做标准化减去列均值除以列标准差如果没有广播你得写循环data np.random.rand(5, 3) # 5行3列 mean np.mean(data, axis0) # shape (3,)每列的均值 std np.std(data, axis0) # shape (3,)每列的标准差 normalized (data - mean) / std这里的(5,3)矩阵减去(3,)的均值向量靠的正是广播mean先被扩展成(1,3)再被复制成(5,3)。如果不想让数组被错误广播np.newaxis是一个好帮手col data[:, 1] # 形状(5,)一维 col2d data[:, 1, None] # 形状(5,1)二维6. ufunc与聚合操作为什么numpy比for循环快到底快在哪儿6.1 通用函数ufunc对数组的整体操作numpy里大量的数学运算都是通过ufunc实现的。所谓ufunc就是universal function的缩写它对数组里的每一个元素执行同样的函数操作而且是在C语言层面循环的。常见的ufunc包括算术运算np.add、np.subtract、np.multiply、np.divide数学函数np.exp、np.log、np.sqrt、np.sin、np.cos比较函数np.greater、np.less、np.equal直接举一个例子x np.array([1, 2, 3]) y np.array([4, 5, 6]) print(np.add(x, y)) # array([5, 7, 9]) print(np.sqrt(x)) # array([1., 1.41421356, 1.7320508]) print(np.exp(x)) # array([ 2.71828183, 7.3890561 , 20.08553692])一个高频踩坑点Python内置的abs函数如果直接用在numpy数组上有时候能跑但性能远不如np.abs而且遇到复数数组时内置abs的行为和np.abs不一致。所以只要操作对象是numpy数组就统一使用np.abs、np.sqrt这类numpy函数。6.2 聚合操作在正确的轴上做统计聚合函数是数据分析的基础操作np.sum、np.mean、np.max、np.min、np.std、np.var、np.argmax、np.argmin等等。很多人对axis参数感到困惑。我的记忆口诀是axis0按列操作axis1按行操作。但这个口诀只在二维情况下成立三维以上就容易出错。更准确的理解是axis0指定的是沿着第0个维度方向滑动把第0个维度压缩掉。mat np.array([[1, 2, 3], [4, 5, 6]]) print(np.sum(mat, axis0)) # array([5, 7, 9])每列求和把行数维度压缩 print(np.sum(mat, axis1)) # array([ 6, 15])每行求和把列数维度压缩np.argmax是返回最大值的索引在分类问题里经常配合softmax的结果来预测标签。比如模型输出概率分布probs形状(batch_size, num_classes)你只需要predictions np.argmax(probs, axis1)得到的predictions就是每个样本最大概率对应的类别下标。6.3 一个具体的性能实测对比让你死心塌地用numpy口说无凭我实际跑一下对比。假设有一个长度为500万的数组我们要计算每个元素的平方和。import time import numpy as np arr np.arange(5000000) # 方法一纯Python for循环 start time.time() total 0 for x in arr: total x * x print(纯Python耗时:, time.time() - start) # 方法二numpy向量化 start time.time() total np.sum(arr ** 2) print(numpy耗时:, time.time() - start)在我的机器上纯Python大概需要1秒左右numpy只需要几毫秒。这个差距来自两处一是numpy在C层面完成循环每秒钟能处理的元素数量远超Python解释器二是numpy底层使用了单指令多数据流SIMD等CPU向量化指令能一次处理多个数据。记住一个原则写numpy代码时如果脑子里冒出来for循环先停一下问问自己能不能用一个ufunc或者聚合函数替代。这几乎是优化numpy代码的第一法则。7. reshape、transpose与矩阵运算把维度玩弄于股掌之上7.1 reshape的深拷贝与浅拷贝陷阱reshape操作非常常用其中有一个细节经常坑人reshape返回的是视图view还是副本copy。大部分情况下reshape返回的是视图意味着它分享原始数据的内存修改视图的数据会改变原始数组。但是当原始数组不是连续内存时reshape可能不得不返回副本。怎么验证可以用np.shares_memorya np.arange(12) b a.reshape(3, 4) print(np.shares_memory(a, b)) # True说明共享内存b是a的视图 b[0, 0] 999 print(a[0]) # 变成了999a也被修改了这个特性在节省内存方面很好用但如果你不希望原始数据被改动一定要用a.reshape(...).copy()。7.2 transpose与轴交换transpose用来交换维度顺序。二维矩阵的转置非常直观就是行列互换mat np.array([[1, 2, 3], [4, 5, 6]]) print(mat.T) # 输出 # [[1 4] # [2 5] # [3 6]]三维以上的转置需要指定轴的排列顺序。比如一个形状(2, 3, 4)的数组执行arr.transpose(2, 0, 1)后维度顺序变成(4, 2, 3)。在深度学习里做图像数据格式转换时比如把(height, width, channels)转成(channels, height, width)就需要这种操作。注意arr.T只适用于二维矩阵的行列互换如果想对高维数组做任意维度的轴交换必须用arr.transpose(...)或np.swapaxes。7.3 矩阵求逆、特征值与线性代数全家桶热搜里的numpy如何求解矩阵的逆答案很直接A np.array([[1, 2], [3, 4]]) A_inv np.linalg.inv(A)但我要提醒一句不要没事就求逆。在解线性方程组时数值上更稳定、效率更高的做法是使用np.linalg.solve# 求解 Ax b b np.array([5, 6]) x np.linalg.solve(A, b)inv和solve的区别在于solve不会显式构造逆矩阵而是直接通过分解方法求解误差更小。学numpy时要养成先想数学问题再想API的习惯。线性代数家族还有几个高频函数整理成表格方便查阅函数作用点评np.linalg.det行列式判断矩阵是否可逆np.linalg.eig特征值与特征向量数据降维、主成分分析基础np.linalg.svd奇异值分解推荐系统、图像压缩常用np.linalg.norm范数正则化里算权重衰减np.linalg.qr/np.linalg.choleskyQR分解/Cholesky分解数值计算底层7.4 实战案例用numpy手写一个最简单的线性回归这一小节把前面讲的很多核心知识点串起来。假设我们要用最小二乘法拟合一条直线y wx b给定一组训练数据x和y我们可以直接用正规方程求解。生成数据时要固定随机种子保证可复现import numpy as np np.random.seed(0) x np.linspace(0, 10, 100) true_w, true_b 2.5, 1.0 y true_w * x true_b np.random.randn(100) * 2这里np.random.randn(100)引入了高斯噪声。接下来构造设计矩阵把常数项1拼进特征矩阵这样偏置b就能被统一当成权重系数了X np.column_stack([x, np.ones_like(x)]) # X形状(100, 2) # 正规方程w (X^T X)^{-1} X^T y theta np.linalg.inv(X.T X) X.T y w, b theta[0], theta[1] print(f拟合得到的w{w:.3f}, b{b:.3f})这一段就用到了column_stack、ones_like、矩阵乘法、转置、求逆、索引多个知识点。跑出来的w和b会非常接近真实的true_w2.5和true_b1.0。做预测时直接用广播机制y_pred w * x b如果你理解了这个案例说明你已经能把numpy的核心操作串起来了。8. 文件读取与保存别等程序关了就一切归零8.1 保存numpy数组的N种形式数据分析或者模型训练过程中经常要把中间结果存下来。numpy提供了轻量级的文件IO方案。使用np.save保存单个数组文件以.npy结尾arr np.array([[1, 2, 3], [4, 5, 6]]) np.save(arr.npy, arr) loaded np.load(arr.npy)使用np.savez一次保存多个数组文件以.npz结尾a np.arange(5) b np.array([1.5, 2.5]) np.savez(data.npz, aa, bb) data np.load(data.npz) print(data[a]) # 通过键名访问在项目里我更喜欢用np.savez因为它可以把不同数组打包在一个文件里方便分享和归档。8.2 用np.loadtxt和genfromtxt处理CSV处理CSV文件是数据分析入门必学技能。下面是一个读取示例# data.csv内容假设为 # name,score # Alice,85 # Bob,92 # Charlie,78 data np.loadtxt(data.csv, delimiter,, skiprows1, dtypestr) print(data)如果你需要直接读取数值矩阵把dtype换成float即可。genfromtxt更宽容即使某一行数据有问题它也能用NaN填充而不是直接崩溃data np.genfromtxt(data.csv, delimiter,, skip_header1, dtypeNone, encodingutf-8)需要注意的是loadtxt默认读出来的是浮点类型如果文件里有字母会直接报错或者转换成NaN。实战中建议先用genfromtxt跑一遍再单独清洗NaN行。9. 一个排错速查表送给每个被numpy折磨过的初学者把常见的错误和解决思路统一放在一个表格里方便你卡住的时候快速对照。报错信息或问题可能原因解决方案ModuleNotFoundError: No module named numpy解释器没选对或环境里真没装用which python和pip list确认环境重新安装安装numpy卡在Installing backend dependencies网络慢pip在拉取构建依赖换清华/阿里镜像源升级pip加--no-cache-dirnumpy 2.x和旧代码不兼容版本太新API变更降级到numpy1.26.4module numpy has no attribute xxx函数根本不在numpy里去scipy或sklearn里找比如trapz在scipy.integrateValueError: operands could not be broadcast together两个数组形状不满足广播规则检查形状用reshape或np.newaxis补维度axis 1 is out of bounds for array of dimension 1一维数组上用了axis1一维数组没有列方向的概念改成axis0pycharm有numpy但代码报错IDE解释器和终端解释器不一致到Project Interpreter里重新选择解释器确认路径统一np.linalg.LinAlgError: Singular matrix矩阵不可逆行列式为0数据有线性相关性换个带正则化的方法或用pinv伪逆这份表格里的问题都是我在实际带人、帮人看代码时遇到的最高频问题。你可以直接截图收藏遇到问题先对照一遍能省下大量翻博客的时间。再补充一个检查习惯代码里只要出现了import numpy as np我就习惯在写完核心逻辑后执行一次np.__version__和np.show_config()来确认当前环境。前者是版本号后者是底层BLAS/LAPACK库的配置情况。如果你发现numpy运算速度奇慢先检查np.show_config()是不是没有链接到优化的BLAS库这在很多官方预编译包里是常见问题。10. numpy之后的下一步先别急着冲深度学习很多初学者学完numpy立刻跳到PyTorch或者TensorFlow结果发现大量时间花在张量形状调试上。我的建议是在numpy和深度学习框架之间先把pandas和matplotlib的基础操作补上。原因很简单实际的数据科学工作流80%的时间都是在清洗数据、处理表格、可视化观察而不是直接怼一个深度模型。pandas就是建立在numpy之上专门处理表格型数据的库它的DataFrame在底层其实就是numpy数组再加上行列标签。而matplotlib画图时你传入的x、y也通常是numpy数组。你把numpy的索引、广播、聚合吃透了pandas的语法上手会非常快因为它们很多操作逻辑是相通的。下次如果你再听到人工智能基础-python-numpy知识点这门课或者这份资料希望你脑子里浮现出来的不是又一段需要死记硬背的API列表而是一块放对了位置的积木。积木不大但是后面所有的高楼大厦都靠它托底。你自己动手把文中的代码敲一遍跑一遍改一改比看二十篇教程都管用。
企业数字化 ERP 产品动态
相关推荐
statsmodels 早期版本演进全览:从 0.1.0b1 到 0.5.0 的功能里程碑与 API 变迁 数据分析数据科学科研 【免费下载链接】statsmodels Statsmodels: statistical modeling and econometrics in Python 项目地址: https://gitcode.com/gh_mirrors/st/statsmodels 点击查看 免费下载 本文基于 statsmodels 仓库中记录 0.5.0 之前全部发布历史的文档… · 2026/9/23 10:48:15
MFC新手避坑:3个致命错误让你项目直接报废 MFC新手避坑:3个致命错误让你项目直接报废 看了一堆教程还是不会写项目?别慌,这太正常了。MFC(Microsoft Foundation… · 2026/9/23 10:48:15
I2C物理层实战:开漏、上拉电阻与多主仲裁真相 1. 这不是教科书,是我在产线修了三年I2C故障后写的“两根线生存指南”你手里的开发板上那两根标着SDA和SCL的细线,看起来平平无奇——可它们一旦出问题,轻则读不到EEPROM,重则整块板子在量产线上卡住,工程师蹲在示波器… · 2026/9/23 10:48:09
IronClaw Google Sheets 扩展解析:get_spreadsheet 元数据操作的设计与实现 人工智能AI 应用交互助手AI Agent 【免费下载链接】ironclaw IronClaw is an Agent OS focused on privacy, security and extensibility 项目地址: https://gitcode.com/gh_mirrors/iro/ironclaw 点击查看 免费下载 本篇文章聚焦 IronClaw 开源仓库中 Google Shee… · 2026/9/23 11:24:39
搞定设备台账模板完整示例:从源码看数据结构设计 搞定设备台账模板完整示例:从源码看数据结构设计 你是不是也遇到过这种情况:刚学完 Python 或 Java,觉得语法都通了,但一接到“做一个设备台账系统”的需求就懵了?… · 2026/9/23 11:24:39
钢材系统源码深扒:3个核心坑点,保姆级教程助你面试通关 钢材系统源码深扒:3个核心坑点,保姆级教程助你面试通关 面试官问“钢材库存并发扣减怎么保证一致性”,你答了“加锁”,追问“锁粒度呢?死锁咋防?”直接卡壳。别慌,这篇 保姆级教程… · 2026/9/23 11:24:39
RTL8111E千兆网卡电路设计:PCIe接口、电源与MDI差分走线实战 简介:这份资源面向硬件工程师与PCB设计初学者,聚焦瑞昱RTL8111E高速以太网控制器的参考电路设计,帮助读者理解千兆网卡从原理图到布局的完整设计思路。压缩包内共1个PDF文件,约75KB,内容为RTL8111E/RTL8111F/RTL8105E的… · 2026/9/23 11:24:39
变异体杀手的诞生之路 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/23 11:24:33
ztoggle 性能优化:3 个核心考点拆解,面试不再卡壳 ztoggle 性能优化:3 个核心考点拆解,面试不再卡壳 翻过几百页的官方文档,却连最基础的 ztoggle 行为都说不清?别慌,这不是你的错。大厂面试官根本不想听你背诵定义,他们只关心你懂不懂底层逻辑,以及如何在高并发场景下做性能优化。… · 2026/9/23 11:24:33
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29